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

来源:互联网 发布:网络协议概念三要素 编辑:程序博客网 时间:2024/05/19 21:40

题目大意:给一个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 1000000000int 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;}

0 0
原创粉丝点击