码迷,mamicode.com
首页 > 其他好文 > 详细

poj 2229

时间:2016-01-05 18:45:39      阅读:219      评论:0      收藏:0      [点我收藏+]

标签:

Sumsets
Time Limit: 2000MS   Memory Limit: 200000K
Total Submissions: 15105   Accepted: 6017

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

 
 
 

有两种做法

第一种是比较暴力的完全背包:

    设状态dp[i]为在总和为i的情况下符合题意的方法总数,因为n不超过2 ^ 20,所以可以把这20个数看成是物品,则可以用完全背包的方法写出状态方程

      dp[i] = dp[i - (1 << j)] ; ((1 << j) <= n)

技术分享
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 
 6 using namespace std;
 7 
 8 const int maxn = 1e6 + 7;
 9 const int mod = 1e9;
10 int dp[maxn];
11 int main() {
12     int n;
13     scanf("%d", &n);
14     dp[0] = 1;
15     for (int i = 0; 1 << i <= n; ++i) {
16         for (int j = 1 << i; j <= n; ++j) {
17             dp[j] = (dp[j] + dp[j - (1 << i)]) % mod;
18         }
19     }
20 
21     printf("%d\n", dp[n]);
22 
23 
24     return 0;
25 }
View Code

第二种是略有技巧性的递推:

     同样设状态dp[i]为在总和为i的情况下符合题意的方法总数,考虑n为奇数和n为偶数的两种情况。

      当n为奇数时,容易知序列中必含有1

        dp[i] = dp[i - 1];

      当n为偶数时,若序列中有1则至少含有两个1,dp[i] += dp[i - 2];

              若序列中没有1,则容易知序列所有数都是偶数,则dp[i] += dp[i / 2];

            两式相加得dp[i] = dp[i - 2] + dp[i / 2];

 

技术分享
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 
 6 using namespace std;
 7 
 8 const int maxn = 1e6 + 7;
 9 const int mod = 1e9;
10 int dp[maxn];
11 int main() {
12     int n;
13     scanf("%d", &n);
14     dp[0] = 1;
15     for (int i = 1; i <= n; ++i) {
16         if (i % 2 == 1) {
17             dp[i] = dp[i - 1];
18         } else {
19             dp[i] = (dp[i - 2] + dp[i / 2]) % mod;
20         }
21     }
22 
23     printf("%d\n", dp[n]);
24 
25 
26     return 0;
27 }
View Code

 

poj 2229

标签:

原文地址:http://www.cnblogs.com/hyxsolitude/p/5103007.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!