• poj 2229


    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
    ", 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
    ", dp[n]);
    24 
    25 
    26     return 0;
    27 }
    View Code
  • 相关阅读:
    Thread与Handler
    开始机顶盒的生涯
    解决布局被键盘顶的难题
    自动滚动的Textview
    2-解决粘包问题
    1-socket编程
    zipfile模块
    subprocess模块
    day31-异常处理
    collections模块
  • 原文地址:https://www.cnblogs.com/hyxsolitude/p/5103007.html
Copyright © 2020-2023  润新知