【动态规划】可接受数列

来源:互联网 发布:mastercam三维编程 编辑:程序博客网 时间:2024/04/26 16:02

可接受数列

【题目描述】

让计算机这样读入一列非负整数:

1、读入数T。                                  

2、接着往下读入T个数。

3、如果数列读完了,则停止,否则,转到1。

但是,往往会出现这样的问题:执行第2步时,数列已经没有T个数了。如果这样,我们称这个数列是“不可接受的”,否则,称它是“可接受的”。我们需要用最少的步数把一个数列变成“可接受的”,一步是指:

1、把数列中的某一个数加1。

2、把数列中的某一个数减1。

 

【输入格式】

第一行有一个数N (1<=N<=1000000),表示数列的长度,接下来有n行,描述这个数列,每一行有一个非负整数(不超过1000000)。

 

【输出格式】

仅一个数,表示最少的步数。

 

【样例】

sequence.in

sequence.out

7

3

1

2

3

4

5

6

1

 

【数据规模】

对于50%的数据,N≤1,000;

对于80%的数据,N≤100,000;

对于100%的数据,N≤1,000,000。


理解错题,导致爆零。

1、把数列中的某一个数加1。

2、把数列中的某一个数减1。

我以为一个数的操作只能加减1,其实可以加减任意数,只是步数不同,同时就算是只能加减1,那么肯定有的会无解,但是题上并没有提到无解。


#include <cstdiO>#include <cstring>#include <string>#define MIN(a,b) ((a)<(b)?(a):(b))#define ABS(a) ((a)<0?-(a):(a))long n;long a[1000010];long f[1000010];long getint(){long rs=0;bool sgn=1;char tmp;do tmp = getchar();while (!isdigit(tmp)&&tmp-'-');if (tmp == '-'){tmp=getchar();sgn=0;}do rs=(rs<<3)+(rs<<1)+tmp-'0';while (isdigit(tmp=getchar()));return sgn?rs:-rs;}int main(){freopen("sequence.in","r",stdin);freopen("sequence.out","w",stdout);n = getint();for (long i=1;i<n+1;i++){a[i] = getint();}memset(f,0x7f,sizeof f);f[1] = 0;for (long i=1;i<n+1;i++){for (long j=-a[i];i+j+a[i]<=n;j++){f[i+j+a[i]+1] = MIN(f[i+j+a[i]+1],f[i]+ABS(j));}//f[i+a[i]+1] = MIN(f[i+a[i]+1],f[i]);//f[i+a[i]+1+1] = MIN(f[i+a[i]+1+1],f[i]+1);//f[i+a[i]-1+1] = MIN(f[i+a[i]-1+1],f[i]+1);}printf("%ld",f[n+1]);return 0;}