【动态规划】可接受数列

可接受数列

【题目描述】

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

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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值