POJ - 2229 Sumsets (完全背包)

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

题意:

    就是给你一个数字,问他能有2^n个数构成,问它能哟噗多少构成方法

思路:

     这道题有递推式,当n为奇数是dp[n] = dp[n - 1],当n为偶数时dp[n] = dp[n - 1] + dp[n/2]

还有一个完全背包:

可以把n想象成一个容量为n的背包 而它能存放的物体为2^0, 2^1, 2^2,...2^k,(2^k <= n) 每一个物体都有无限个,dp[n] += dp[n-a[i]]为,为什么要加上,因为dp[k]原本的含义是没有因子a[i]的种类数,有了因子a[i]后,要加上不含的,才是一共的。

AC 代码:

//
//  main.cpp
//  B - Sumsets
//
//  Created by dhl on 2018/7/17.
//  Copyright © 2018年 dhl. All rights reserved.
//

#include <iostream>
#include <string.h>
using namespace std;
int mod = 1000000000;
int dp[1000005];
int a[30];
int main(int argc, const char * argv[]) {
    int n;
    cin >> n;
    a[0] = 1;
    int i;
    for (i = 1; a[i - 1] <= 1000000; i ++) {
        a[i] = a[i - 1] * 2;
    }
    memset(dp, 0, sizeof(dp));
    dp[0] = 1;
    for (int j = 0; j < i ; j ++) {
        if (a[j] > n) break;
        for (int k = a[j]; k <= n; k ++) {
            dp[k] = (dp[k - a[j]] + dp[k]) % mod;
        }
    }
    cout << dp[n] << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/henu_jizhideqingwa/article/details/81089739