Sumsets
Time Limit:2000 MS |
|
Memory Limit:200000 K |
Total Submissions:10974 |
|
Accepted:4419 |
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
USACO 2005 January Silver I started to think of as a full backpack, logn items, so the complexity of nlogn. The results are infinite. TLE is speechless. Then I searched for the question and found O (n) practices, which were quite clever. When n is an odd number, dp [n] = dp [n-1], because it must contain 1, therefore, each addition of 1 in dp [n-1] corresponds to dp [n] One by one. When n is an even number, it either contains at least 2 1, or does not include 1, if the value is not 1, the number of methods is to multiply each item of dp [n/2] by the value of 2. So dp [n] = dp [N-2] + dp [n/2]. Finally, the nlogn solution can be used. I just got stuck in two seconds to change the mod operation to subtraction. O (nlogn)
int dp[25][maxn];void solve(){ memset(dp,0,sizeof(dp)); for(int i = 0;i < 25;i++) dp[i][1] = dp[i][0] = 1; for(int i = 1;i < 25;i++){ for(int j = 2;j < maxn;j++){ int v = 1 << (i-1); if(j >= v) dp[i][j] = (LL(dp[i][j-v]) + dp[i-1][j]); else dp[i][j] = dp[i-1][j]; while(dp[i][j] > Mod) dp[i][j] -= Mod; } }}int main(){ int n; solve(); while(cin >> n){ cout << dp[24][n] << endl; } return 0;}
O (n)
LL dp[maxn];void solve(){ dp[0] = 1; for(int i = 1;i < maxn;i++){ if(i%2 == 1) dp[i] = dp[i-1]; else dp[i] = (dp[i-2] + dp[i/2]) % Mod; }}int main(){ int n; solve(); while(scanf("%d",&n) != EOF){ printf("%d\n",dp[n]); } return 0;}