Sumsets

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值