poj2229 简单DP

来源:互联网 发布:剑网3成男脸型数据 编辑:程序博客网 时间:2024/06/02 06:58

题意 把n拆分为2的幂相加的形式,问有多少种拆分方法。

思路 比较好的DP方案开始没有想到,所以这里列出两种方案吧

   (1)DP(i,j)表示第i个数,最小数由2的j次方来组合得到的方案数。

状态转移dp[i][j] = (dp[i][j+1] + dp[i-(1<<j)][j])

初始条件 dp(1,0) = 1

   (2)更好更简单的方法是分奇偶考虑,奇数时就是dp(i) = dp(i-1),偶数时dp(i) = dp(i-1)+dp(i/2)

dp(i-1)表示i由最小数由1来组合得到的方案数,比较好理解。

dp(i/2)表示i由最小数由2来组合得到的方案数,这是因为组成i/2的方案所有数乘2即是组成i的方案。


实现 这里就给出第一个方案的代码,第二个过于简单不列出了。

#include <iostream>#include <cstdio>#include <cmath>#include <cstring>#include <vector>using namespace std;#define MAX 1000005#define MOD 1000000000int n;int dp[MAX][20];int main(){cin>>n;int i,j;dp[1][0] = 1;int now = 1;for(i=2;i<=n;i++){if(i == (1<<now)){dp[i][now] = (dp[i][now] + 1) % MOD;now++;}for(j=now-1;j>=0;j--){if(i-(1<<j) < (1<<j))continue;dp[i][j] = (dp[i][j+1] + dp[i-(1<<j)][j])%MOD;}}cout<<dp[n][0]<<'\n'; return 0;}


0 0