SUBTRACT
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 2037   Accepted: 901   Special Judge

Description

We are given a sequence of N positive integers a = [a1, a2, ..., aN] on which we can perform contraction operations. 
One contraction operation consists of replacing adjacent elements ai and ai+1 by their difference ai-ai+1. For a sequence of N integers, we can perform exactly N-1 different contraction operations, each of which results in a new (N-1) element sequence.

Precisely, let con(a,i) denote the (N-1) element sequence obtained from [a1, a2, ..., aN] by replacing the elements ai and ai+1 by a single integer ai-ai+1 :

con(a,i) = [a1, ..., ai-1, ai-ai+1, ai+2, ..., aN] 
Applying N-1 contractions to any given sequence of N integers obviously yields a single integer. 
For example, applying contractions 2, 3, 2 and 1 in that order to the sequence [12,10,4,3,5] yields 4, since :

con([12,10,4,3,5],2) = [12,6,3,5]

con([12,6,3,5] ,3) = [12,6,-2]

con([12,6,-2] ,2) = [12,8]

con([12,8] ,1) = [4]

Given a sequence a1, a2, ..., aN and a target number T, the problem is to find a sequence of N-1 contractions that applied to the original sequence yields T.

Input

The first line of the input contains two integers separated by blank character : the integer N, 1 <= N <= 100, the number of integers in the original sequence, and the target integer T, -10000 <= T <= 10000. 
The following N lines contain the starting sequence : for each i, 1 <= i <= N, the (i+1)st line of the input file contains integer ai, 1 <= ai <= 100. 

Output

Output should contain N-1 lines, describing a sequence of contractions that transforms the original sequence into a single element sequence containing only number T. The ith line of the output file should contain a single integer denoting the ithcontraction to be applied. 
You can assume that at least one such sequence of contractions will exist for a given input. 

Sample Input

5 4
12
10
4
3
5

Sample Output

2
3
2
1

Source

题意:

给N个数,每次选定一个i,用a[i] - a[i+1]的结果取代a[i]和a[i+1]。操作N-1次之后,就只剩下1个数。问如何选择,可以使这个数恰好是T

思路:

我们可以发现,这个序列每次用减来取代的话,其实就是在n个数之前加上正负,然后让他们都加起来的和结果是T。

而且a[1]一定是正,a[2]一定是负。

于是我们用dp[i][j]来表示第i个数得到分数j时的符号,1表示是加,-1表示是减,0表示没有扩展到。【我怎样才能聪明地想到要这样来表示呢】

我们枚举i,j,判断上一个状态i-1有没有扩展到当前分数j。如果有,那么dp[i][j + a[i]] = 1, dp[i][j - a[i]] = -1

然后我们从dp[n][t]开始倒推出每一个元素之前的符号。ans[i]表示的就是a[i]前的符号。

那么方案该怎么输出?

先去处理所有的加号,相当于把所有的加号都挪去了原来a3的位置,这样最后处理减号的时候,减a2就可以负负得正了。

然后处理减号,把所有的减号都挪到了原来a2的位置,给a1来减。

 //#include <bits/stdc++.h>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<stdio.h>
#include<cstring>
#include<vector>
#include<map>
#include<set> #define inf 0x3f3f3f3f
using namespace std;
typedef long long LL; int n, t;
int a[];
int dp[][], ans[];
const int base = ; int main()
{
while(scanf("%d%d", &n, &t) != EOF){
for(int i = ; i <= n; i++){
scanf("%d", &a[i]);
}
memset(dp, , sizeof(dp));
dp[][a[] + base] = ;
dp[][a[] - a[] + base] = -;
for(int i = ; i <= n; i++){
for(int j = - + base; j <= + base; j++){
if(dp[i - ][j] != ){
dp[i][j + a[i]] = ;
dp[i][j - a[i]] = -;
}
}
} int want = t + base;
for(int i = n; i >= ; i--){
ans[i] = dp[i][want];
if(ans[i] == ){
want -= a[i];
}
else if(ans[i] == -){
want += a[i];
}
} int cnt = ;
for(int i = ; i <= n; i++){
if(ans[i] == ){
printf("%d\n", i - cnt - );
cnt++;
}
}
for(int i = ; i <= n; i++){
if(ans[i] == -){
printf("1\n");
}
}
}
return ;
}

poj1722 SUBTRACT【线性DP】的更多相关文章

  1. LightOJ1044 Palindrome Partitioning(区间DP+线性DP)

    问题问的是最少可以把一个字符串分成几段,使每段都是回文串. 一开始想直接区间DP,dp[i][j]表示子串[i,j]的答案,不过字符串长度1000,100W个状态,一个状态从多个状态转移来的,转移的时 ...

  2. Codeforces 176B (线性DP+字符串)

    题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=28214 题目大意:源串有如下变形:每次将串切为两半,位置颠倒形成 ...

  3. hdu1712 线性dp

    //Accepted 400 KB 109 ms //dp线性 //dp[i][j]=max(dp[i-1][k]+a[i][j-k]) //在前i门课上花j天得到的最大分数,等于max(在前i-1门 ...

  4. 动态规划——线性dp

    我们在解决一些线性区间上的最优化问题的时候,往往也能够利用到动态规划的思想,这种问题可以叫做线性dp.在这篇文章中,我们将讨论有关线性dp的一些问题. 在有关线性dp问题中,有着几个比较经典而基础的模 ...

  5. POJ 2479-Maximum sum(线性dp)

    Maximum sum Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 33918   Accepted: 10504 Des ...

  6. poj 1050 To the Max(线性dp)

    题目链接:http://poj.org/problem?id=1050 思路分析: 该题目为经典的最大子矩阵和问题,属于线性dp问题:最大子矩阵为最大连续子段和的推广情况,最大连续子段和为一维问题,而 ...

  7. nyoj44 子串和 线性DP

    线性DP经典题. dp[i]表示以i为结尾最大连续和,状态转移方程dp[i] = max (a[i] , dp[i - 1] + a[i]) AC代码: #include<cstdio> ...

  8. 『最大M子段和 线性DP』

    最大M子段和(51nod 1052) Description N个整数组成的序列a[1],a[2],a[3],-,a[n],将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的.如果M &g ...

  9. 『最长等差数列 线性DP』

    最长等差数列(51nod 1055) Description N个不同的正整数,找出由这些数组成的最长的等差数列. 例如:1 3 5 6 8 9 10 12 13 14 等差子数列包括(仅包括两项的不 ...

  10. cf909C 线性dp+滚动数组好题!

    一开始一直以为是区间dp.. /* f下面必须有一个s 其余的s可以和任意f进行匹配 所以用线性dp来做 先预处理一下: fffssfsfs==>3 0 1 1 dp[i][j] 表示第i行缩进 ...

随机推荐

  1. e553. 作为浏览器访问URL

    // See also e551 精简的Applet try { URL url = new URL(getDocumentBase(), "http://hostname.com/page ...

  2. DOM编程 学习笔记(一)

    PS:虽然自己JS基本语法算是掌握了,但是其实在JS掌握的只是远远还不够,网页上有太多好看的动态效果都是用JS 做出来的,自己也就仅仅会那么一两个动态的效果,学的只是皮毛...等有空的时候一定要好好的 ...

  3. 小明A+B(杭电2096)

    /*小明A+B Problem Description 小明今年3岁了, 如今他已经可以认识100以内的非负整数, 而且可以进行100以内的非负整数的加法计算. 对于大于等于100的整数, 小明仅保留 ...

  4. tagVARIANT、VARIANT、_variant_t和COleVariant

    tagVARIANT是一个结构体struct:  C++ Code: tagVARIANT 123456789101112131415161718192021222324252627282930313 ...

  5. Mike Gancarz:Linux/Unix设计思想

           Mike Gancarz是一位技术布道者. 他是Linux/Unix最基本的倡导者之中的一个,也是最早开发X Window System的先驱.他把一些在Unix/Linux社区里口口相 ...

  6. dos命令临时和永久设置环境变量方法

    方法一:批处理中,修改环境变量,一次性有效(也就是在当前的脚本中有效)   CMD中运行:set path==%path%;d:/mypath   用 set path可以查看,当前的环境变量   方 ...

  7. HTTP 请求过程

    如下,我们在浏览器输入一个域名,按回车之后,便向该域名对应的服务器发送了一个请求:服务器接收到这个请求后进行处理和解析,然后返回响应的内容给浏览器,浏览器再对其进行解析然后呈现网页 我们可以通过 Ch ...

  8. windows命令之PING DIR DEL CD TASKLIST (转)

    最简单的莫过于PING命令了. PING命令的功能就是给对方主机发送IP数据包. 一般都是测试主机是否在线. 用法如下: PING 192.168.1.1.PING命令默认发送的是四个数据包,当然也可 ...

  9. Effective C++ —— 杂项讨论(九)

    条款53 : 不要轻忽编译器的警告 请记住: 1. 严肃对待编译器发出的警告信息.努力在你的编译器的最高(最严苛)警告级别下争取“无任何警告”的荣誉. 2. 不要过度倚赖编译器的报警能力,因为不同的编 ...

  10. js禁止img拖动

    其实只需要一句代码即可,那就是阻止元素的默认事件: <body> <img src="./../imgs/cat.jpg" id="test" ...