整数拆分

时间限制:1秒 空间限制:65536K
题目描述
一个整数总可以拆分为2的幂的和,例如: 7=1+2+4 7=1+2+2+2 7=1+1+1+4 7=1+1+1+2+2 7=1+1+1+1+1+2 7=1+1+1+1+1+1+1 总共有六种不同的拆分方式。 再比如:4可以拆分成:4 = 4,4 = 1 + 1 + 1 + 1,4 = 2 + 2,4=1+1+2。 用f(n)表示n的不同拆分的种数,例如f(7)=6. 要求编写程序,读入n(不超过1000000),输出f(n)%1000000000。
输入描述:
每组输入包括一个整数:N(1<=N<=1000000)。
输出描述:
对于每组数据,输出f(n)%1000000000。
示例1
输入
7
输出
6

起初想打表:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MOD 1000000000

long A[5000];

int main() {
	long N,res;

	memset(A,0,sizeof(A));
	for(int i=0; i<=1; i++) {
		for(int j=0; j<=2; j++) {
			for(int k=0; k<=4; k++) {
				for(int l=0; l<=8; l++) {
					for(int m=0; m<=16; m++) {
						for(int n=0; n<=32; n++) {
							res=32*i+16*j+8*k+4*l+2*m+n;
							if(res<=32)
							   A[res]++;
						}
					}
				}
			}
		}
	}
	for(int i=1; i<=32; i++) {
		printf("%ld %ld\n",i,A[i]) ;
	}

	return 0;
}

但我竟然没看出来递推公式:
f(2m + 1) = f(2m),
f(2m) = f(2m - 1) + f(m),
初始条件:f(1) = 1。

动态规划如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MOD 1000000000

int dp[1000005];
int a[21];

int main() {
	for(int i=1;i<=20;i++){
		a[i]=1<<(i-1);
	}
	int N;
	while(scanf("%d",&N)!=EOF){
		memset(dp,0,sizeof(dp));
		dp[0]=1;
		for(int i=1;i<20;i++){
			for(int j=a[i];j<=N;j++){
				dp[j]+=dp[j-a[i]]; 
				dp[j]%=MOD;
			}
		}
		printf("%d",dp[N]);
	} 
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值