Poj 2229 Sumsets 代码及易错分析

这题,作为菜鸡的我使用暴力找规律.

在这里显然发现 如果N为奇数,则DP[N]=DP[N-1];

然后我们继续往下寻找规律。

在这里我写的很清楚了  任意偶数都可以表示成 DP[N]=DP[N-1]+DP[N/2];

下面我给出我的暴力代码,读者自行验证规律。

#include <cstdio>
using namespace std;
int main()
{
	int count=0;
	int n;
	scanf ("%d",&n);
	for (int i=0;i<=n;i++)
		for (int j=0;j<=n/2;j++)
			for (int k=0;k<=n/4;k++)
				for (int p=0;p<=n/8;p++)
					for (int q=0;q<=n/16;q++)
						for (int r=0;r<=n/32;r++)
						if (i+2*j+k*4+p*8+16*q+32*r==n)
						{
						//	printf("%d 1,%d 2,%d 4,%d 8,%d 16 \n",i,j,k,p,q);
								count++;
						}
	printf("%d\n",count);
}

结合之前的两个规律,我们可以写出我们的答案了。

#include <cstdio>
using namespace std;
long long dp[1000100]={0};
const int mod=1e9;
int main()
{
	int n,k=0;
	long long count;
	dp[1]=1;
	dp[2]=2;
	for (int i=3;i<=1000010;++i)
	{
		if (i%2==1)
			dp[i]=dp[i-1];
		else
			dp[i]=(dp[i-2]+dp[i/2])%mod;
	}
	while (~scanf ("%d",&n))
	{	
		count=dp[n]%mod;
		printf("%lld\n",count);
	}
	return 0;
}

但是我们要注意一个地方,我们在记录数据是要进行Mod,不然答案会错,说明中间数据真的很大。

猜你喜欢

转载自blog.csdn.net/qq_34022601/article/details/83044496