zoukankan      html  css  js  c++  java
  • POJ:2229-Sumsets(完全背包的优化)

    题目链接:http://poj.org/problem?id=2229

    Sumsets

    Time Limit: 2000MS Memory Limit: 200000K
    Total Submissions: 21845 Accepted: 8454

    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


    解题心得:

    1. 问给你一系列2的N次方的数,让你用这些数相加起来等于m,问一共有多少种方法。
    2. 刚开始看到这个题的时候第一个反应就是青蛙跳台阶的问题(链接),按照这个思路状态转移就出来了。dp[n][m] += dp[n-1][m-k*c[i]],在空间上优化可以使用滚动数组来进行优化。这样还是会TLE,因为没有优化过的完全背包是三重循环,这个时候就需要用到完全背包的优化,完全背包的优化其实很简单,思想就是既然背包有无穷多个,那么直接从小到大开始叠加就行了,会自然叠加到最大,这样就可以省去k个背包的循环,利用的就是k无穷大不用一一进行枚举。可以很简单的看懂优化代码。

    没有优化过的完全背包(大概写法):

    for(int i=0;i<n;i++) {
        for(int k=1;k*c[i] <= n;k++) {
            for(int j=m;j>=k*c[i];k--) {
                dp[j] += dp[j-k*c[i]];
            }
        }
    }

    完全背包的时间优化(大概写法):

    for(int i=0;i<n;i++) {
        for(int j=c[i];j<=n;j++) {//注意这里是从小到大开始叠加
            dp[j] += dp[j-c[i]];
        }
    }

    AC代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = (int) 1e6 + 10;
    int n, dp[maxn];
    int Mod = (int) 1e9;
    
    int main() {
        int T = 1;
        while (~scanf("%d", &n)) {
            memset(dp, 0, sizeof(dp));
            dp[0] = 1;
            while (T <= n) {
                for (int j = T; j <= n; j++) {
                    dp[j] += dp[j - T];
                    dp[j] %= Mod;
                }
                T <<= 1;
            }
            printf("%d
    ", dp[n]);
            return 0;
        }
    }
  • 相关阅读:
    常用模块(time,os,sys,collections,random,序列化模块,re)
    python-函数篇
    内置函数——filter和map
    python杂七杂八的用法
    计算机硬件
    操作系统简介
    Django入门
    linux下查看cpu物理个数和逻辑个数
    python反射的妙用
    Python(文件、文件夹压缩处理模块,shelve持久化模块,xml处理模块、ConfigParser文档配置模块、hashlib加密模块,subprocess系统交互模块 log模块)
  • 原文地址:https://www.cnblogs.com/GoldenFingers/p/9107118.html
Copyright © 2011-2022 走看看