可接受数列
【题目描述】
让计算机这样读入一列非负整数:
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;
}