Sumsets (poj 2229 简单dp)

24 篇文章 0 订阅

Sumsets
Time Limit: 2000MS Memory Limit: 200000K
Total Submissions: 13791 Accepted: 5482

Description

Farmer John commanded his cows to search for different sets of numbers that sum to a given number. The cows use only numbers that are an integer power of 2. Here are the possible sets of numbers that sum to 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 

Help FJ count all possible representations for a given integer N (1 <= N <= 1,000,000). 

Input

A single line with a single integer, N.

Output

The number of ways to represent N as the indicated sum. Due to the potential huge size of this number, print only last 9 digits (in base 10 representation).

Sample Input

7

Sample Output

6

Source


题意:给一个整数n,求解该整数n有多少种由2的幂次之和组成的方案。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define maxn 1000010
#define MAXN 2005
#define mod 1000000000
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define FRE(i,a,b)  for(i = a; i <= b; i++)
#define FRL(i,a,b)  for(i = a; i < b; i++)
#define mem(t, v)   memset ((t) , v, sizeof(t))
#define sf(n)       scanf("%d", &n)
#define sff(a,b)    scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf          printf
#define DBG         pf("Hi\n")
typedef long long ll;
using namespace std;

int dp[maxn];

void solve()
{
    dp[1]=1;
    dp[2]=2;
    for (int i=3;i<maxn;i++)
    {
        if (i%2)
            dp[i]=dp[i-1];  //当i为奇数时,i-1必定是偶数,i是在i-1的二进制的最低位加1而来,所以dp[i]=dp[i-1]
        else
            dp[i]=(dp[i-2]+dp[i/2])%mod;//当i为偶数时,则可以划分成前面有1组成而后两位必是0的二进制表示和两部分都表示偶数的二进制,即dp[i]=dp[i-2]+dp[i/2].
    }
}

int main()
{
    int i,j,n;
    solve();
    while (~sf(n))
        pf("%d\n",dp[n]);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值