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;
}