//递推
题意:给出一个整数n,求解该整数n有多少种由2的幂次之和组成的方案.
这里将n用二进制表示,当n为奇数时,n-1必定是偶数,n是在n-1的二进制的最低位加1而来,所以num[i]=num[i-1]
而当n为偶数时,则可以划分成前面有1组成而后两位必是0的二进制表示和两部分都表示偶数的二进制,即num[i]=num[i-2]+num[i/2].
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int e[1000005];
int main(){
int i;
e[1]=1;
e[2]=2;
for(i=3;i<=1000000;i++){
if(i%2==1)
e[i]=e[i-1];
else
e[i]=(e[i-2]+e[i/2])%1000000000;
}
int n;
while(~scanf("%d",&n)){
printf("%d\n",e[n]);
}
return 0;
}
//dp状态:
d[i][j]表示前i个二的幂数凑成数j的方法数
空间可以降维到d[j]
状态转移方程:
d[j]=d[j]+d[j-c[i]]
c[i]=2^i
边界:
d[0]=1
#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(i=0;i<=20&&c[i]<=n;i++)
for(j=c[i];j<=n;j++)
d[j]=(d[j]+d[j-c[i]])%1000000000;
printf("%d/n",d[n]);
}