SUBTRACT
给出一个长度为n序列\(\{a_i\}\),定义一个操作,记做\(con(a,i)\),意思是用\(a_i-a_{i+1}\)替代\(a_i,a_{i+1}\),显然最后一个数字不能进行这样的操作,序列也最多只能进行n-1次操作,而且最后序列会剩下一个数字,求它刚好为t的操作方案,\(1 <= N <= 100,1 <= ai <= 100\)。
解
显然,当前的模型是不能进行递推的,因为序列长度在改变,于是有以下性质
性质1
假设序列为\(\{a,b,c\}\),进行操作大概如此
a b c
a-b c
a-b-c
a b c
a b-c
a-b+c
于是我们发现所谓的操作,也就是给序列的各个数字前添上+,-号,不难发现第一个数字前必然是+,第2个数字必然是-,问题是不知道后面的+,-序列是否合法,不妨猜测它是合法的,但是暂时没办法证明。
性质2
如果把替代后的数用括号看成一个整体
a b c
a (b-c)
(a-(b-c))
于是发现问题转化为刚开始序列只有第一个数字前面为+,后面的全为-,要添上括号,并保证每一个数都被扩到(也就是碰到括号边界),而我们的加减序列,只是被去掉了括号,这条性质是便于理解。
性质3
性质1留下一个疑问,就是怎样的+,-序列才是合法的,既然不知道,猜测无论如何都是合法的,首先能够发现的是一个加减序列为\(a-b-c-d\),即第一个+,后面全是-,我们一定能够不停地对第一个数进行操作使之合法,对于只有两个数一定第二个数符号为-才是让这两个数被加上括号,因此关键在+
于是对于一个+,-序列而言,遇到+,我们肯定要想办法变为-,而要使之为-,必然前面要有-,让之变为-,于是对于一段连续的+,我们都可以进行这样的操作,而注意到第二个数一定有一个-,因此无论如何后面有+的数总会有-,因此后面无论+-情况如何,总能成为一个合法的操作序列。
而且也告诉我们,成为操作序列的办法是,遇加变减即可。
有了这三条性质,我们注意到数字很小,现在问题是该数字是选+还是-,让之最后结果正好为t,于是可以暴力压维保存t,因为并没有求最优性问题,递推数组可以顺便保存方案,1表示这里选+,-1表示这里选-,因此设\(f[i][j]\)表示前i个数权值正好为j的i的符号(0表示这是非法状态),用顺转移有
\(if(f[i][j])\)
\]
边界:\(f[1][a_1]=1,f[2][a_2]=-1\)
答案:\(f[n][t]\)
参考代码:
#include <iostream>
#include <cstdio>
#define il inline
#define ri register
#define zero 10000
using namespace std;
int a[101],dp[101][20010],
ans[101];
void getans(int,int);
int main(){
int n,t;scanf("%d%d",&n,&t);
for(int i(1);i<=n;++i)scanf("%d",&a[i]);
dp[1][zero+a[1]]=1,dp[2][zero+a[1]-a[2]]=-1;
for(int i(2),j;i<n;++i)
for(j=0;j<=20000;++j)
if(dp[i][j])
dp[i+1][j+a[i+1]]=1,
dp[i+1][j-a[i+1]]=-1;
getans(n,t+zero);int tot(2);
for(int i(2);i<=n;++i){
while(ans[i+1]==1&&i<=n)++i,printf("%d\n",tot);++tot;
}--tot;while(--tot)puts("1");
return 0;
}
void getans(int a,int b){
if(!a)return;ans[a]=dp[a][b];
getans(a-1,b-dp[a][b]*::a[a]);
}
SUBTRACT的更多相关文章
- RDD常用方法之subtract&intersection&cartesian
subtract Return an RDD with the elements from `this` that are not in `other` . def subtract(othe ...
- [CareerCup] 7.4 Implement Multiply Subtract and Divide 实现乘法减法和除法
7.4 Write methods to implement the multiply, subtract, and divide operations for integers. Use only ...
- add, subtract, multiply, divide
加.减.乘.除:add, subtract, multiply, divide
- MongoDB比较两列大小 使用$subtract函数
是找出整个表 a大于b的总数量,要怎么操作数据库呢,那就要用到$subtract函数 MongoDB比较两列大小 使用$subtract函数, // MongoDB 比较两列大小求出 啊>b 的 ...
- poj1722 SUBTRACT【线性DP】
SUBTRACT Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2037 Accepted: 901 Special ...
- Spark 学习笔记之 union/intersection/subtract
union/intersection/subtract: import org.apache.spark.SparkContext import org.apache.spark.rdd.RDD im ...
- C# DateTime Subtract
DateTime start = DateTime.Now.AddDays(-20); DateTime end = DateTime.Now; TimeSpan ts = end.Subtract( ...
- 【java】Java.math.BigDecimal.subtract()方法实例
java.math.BigDecimal.subtract(BigDecimal subtrahend) 返回一个BigDecimal,其值为 (this - subtrahend), 精度为 max ...
- deep_learning_Function_tf.add()、tf.subtract()、tf.multiply()、tf.div()
tf.add().tf.subtract().tf.multiply().tf.div()函数介绍和示例 1. tf.add() 释义:加法操作 示例: x = tf.constant(2, dtyp ...
随机推荐
- centos7部署汉化版gitlab
=============================================== 2018/6/5_第7次修改 ccb_warlock 更新说 ...
- 7年Java后端被淘汰,一路北漂辛酸史。。。
作者:春天花会开foryou oschina.net/question/3465562_2281392 今天分享一位同行的经历: 本人Java开发6年半不到7年的样子. 英语专业,临毕业跟着隔壁专业去 ...
- 净心诀---python3生成器进阶
列表推导式 把需要用一个函数写成的小功能,利用一行表达式完成 例子: l = [1,2,3,4,5] # 所有的偶数都放到新的列表中 # 正常函数 def Lst(): li = [] for i i ...
- vue 路由传参中刷新页面参数丢失 及传参的几种方式?
在页面跳转中,我通过路由传参,结果发现页面参数丢失了.路径返回了根目录.... 1. 先说下路由传参的几种方式吧? 比如:<div v-for="item in items" ...
- 2018-2-13-win10-uwp-入门
title author date CreateTime categories win10 uwp 入门 lindexi 2018-2-13 17:23:3 +0800 2018-2-13 17:23 ...
- codeforces 24d Broken robot 期望+高斯消元
题目传送门 题意:在n*m的网格上,有一个机器人从(x,y)出发,每次等概率的向右.向左.向下走一步或者留在原地,在最左边时不能向右走,最右边时不能像左走.问走到最后一行的期望. 思路:显然倒着算期望 ...
- 关于ajax请求status 200 却进入error 回调函数或显示跨域问题的解决方案及原因
这虽然不是前端的问题吧,但如果遇到那种不靠谱的后台 还是可以拿来打脸的 转:https://segmentfault.com/a/1190000012469713
- quartz的使用(二.基本过程)
1.关于各个要素的创建,SchedulerFactoryBean,CronTriggerFactoryBean及JobDetailFactoryBean全部实现spring中的FactoryBean& ...
- CRI 与 ShimV2:一种 Kubernetes 集成容器运行时的新思路
摘要: 关于 Kubernetes 接口化设计.CRI.容器运行时.shimv2.RuntimeClass 等关键技术特性的设计与实现. Kubernetes 项目目前的重点发展方向,是为开发 ...
- 如何通过编程发现Java死锁
本文由 ImportNew - rookie_sam 翻译自 Dzone.欢迎加入翻译小组.转载请见文末要求. 死锁是指,两个或多个动作一直在等待其他动作完成而使得所有动作都始终处在阻塞的状态.想要在 ...