poj 2229 2的次方个数dp

来源:互联网 发布:大二java课程设计题目 编辑:程序博客网 时间:2024/06/05 20:23

题意:

给一个数n,求用2的t次方的数来加成这个数,能有几种方法。

结果对1e9取模。

e.g:

7可以有以下6种加法:

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


解析:

当i为奇数的时候:

dp[i] = dp[i - 1]

就是直接+个1就到当前情况了;


当i为偶数的时候:

dp[i] = dp[i - 1] + dp[i>>1]

意思是当i为偶数的时候,拆成一个奇数,还是拆成原来的偶数。

若拆成奇数+1到达当前,则=dp[i - 1],若拆成偶数相加到当前i,则相当于i/2的方案数。


代码:

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <climits>#include <cassert>#define LL long long#define lson lo, mi, rt << 1#define rson mi + 1, hi, rt << 1 | 1using namespace std;const int maxn = 1e6 + 10;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);LL dp[maxn];void init(){    dp[1] = 1;    dp[2] = 2;    for (int i = 3; i < maxn; i++)    {        if (i & 1)        {            dp[i] = dp[i - 1];        }        else        {            dp[i] = (dp[i - 1] + dp[i >> 1]) % 1000000000;        }    }}int main(){#ifdef LOCAL    freopen("in.txt", "r", stdin);#endif // LOCAL    init();    int n;    while (~scanf("%d", &n))    {        printf("%lld\n", dp[n]);    }    return 0;}


0 0
原创粉丝点击