(不易)POJ-2229 DP,数的分解

题目大意:给一个N,N可以分解为2的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 

一共6种。      输出N可以分解的种数(结果%1e9)。


题目链接:点击打开链接


分析:

状态:dp[i]表示i的满足条件的种数

然后先来看奇数,对于一个奇数i来说,无论无何怎么分解都会剩下一个1,除了这个1之外其他的组合跟i-1是等价的。

所以 dp[i] = dp[i-1]


然后对于偶数i,我们可以把它的分解方式分成2部分,

①分解的数里不含1,以4为例,则有 2+2 和 4 两种方式,由于不含1且都是2的倍数,我们可以提取一个公因子2变成了(1+1)*2和(2)*2,此时刚好等价于在 i/2 的分解上乘以2,所以此时的种类为dp[i/2]

②分解的数里含1,所以分解的数里至少含有1个1,我们将这个1先挪到一边,剩下的刚好就是 i-1所对应的分解种数即

dp[i-1](或dp[i-2]因为i-1为奇数)

所以 dp[i] = dp[i/2] + dp[i-1]


附上代码:

#include<iostream>
#include<algorithm>
using namespace std;
#define Y 1000000000
int n;
int dp[1000000+5];
int main()
{
	scanf("%d", &n);
	dp[1] = 1;
	for (int i = 2; i <= n; i++)
		if (i % 2) dp[i] = dp[i - 1];
		else dp[i] = (dp[i / 2] + dp[i - 1]) % Y;
	printf("%d\n", dp[n]);
	return 0;
}

你可能感兴趣的:(dp,ACM,题解报告)