这题,作为菜鸡的我使用暴力找规律.
在这里显然发现 如果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,不然答案会错,说明中间数据真的很大。