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