http://poj.org/problem?id=2229
Description
找一些2^x(0<=x),使它们的和为N。比如,N=7:
1) 1+1+1+1+1+1+1
2) 1+1+1+1+1+2
3) 1+1+1+2+2
4) 1+1+1+4
5) 1+2+2+2
6) 1+2+4
(1 <= N <= 1,000,000).
Input
N.
Output
排列方式总数。由于这个数可能很大,只需要保留最后9位
Sample Input
7
Sample Output
6
Hint
打表的会被系统自动识别判为WA
思路:
通过找题解,发现还有一种写法
将n用二进制表示,当n为奇数时,n-1必定是偶数,n是在n-1的二进制的最低位加1而来,所以num[i]=num[i-1] 而当n为偶数时,则可以划分成前面有1组成而后两位必是0的二进制表示和两部分都表示偶数的二进制,即num[i]=num[i-2]+num[i/2].
下面的代码是常规的dp写法,
#include<cstdio>
int d[1000005],c[25],n,i,j;
int main()
{
scanf("%d",&n);
c[0]=d[0]=1;
for(i=1;i<=20;i++)
c[i]=c[i-1]<<1;
for(int i=0;i<=20&&i<n;i++)
{
for(int j=c[i];j<=n;j++)
{
d[j]=(d[j]+d[j-c[i]])%1000000000;
}
}
printf("%d\n",d[n]);
}