zoukankan      html  css  js  c++  java
  • HDU 2844 Coins (多重背包问题DP)

    题意:给定n种硬币,每种价值是a,数量是c,让你求不大于给定V的不同的价值数,就是说让你用这些硬币来组成多少种不同的价格,并且价格不大于V。

    析:一看就应该知道是一个动态规划的背包问题,只不过是变形,那我们就统计不大于V的不同价格数,也容易实现,

    对于多重背包我们是把它转化为01背包和完全背包来解决的。

    代码如下:

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    
    using namespace std;
    typedef long long LL;
    const int maxn = 100000 + 10;
    int d[maxn];
    int c[maxn], a[maxn], V;
    
    void zeroonepack(int v, int val){
        for(int i = V; i >= v; --i)
            d[i] = max(d[i], d[i-v]+val);
    }
    
    void completepack(int v, int val){
        for(int i = v; i <= V; ++i)
            d[i] = max(d[i], d[i-v]+val);
    }
    
    void multiplepack(int v, int val, int num){
        if(V <= num * v){  completepack(v, val);  return ; }
    
        int k = 1;
        while(k <= num){
            zeroonepack(v*k, val*k);
            num -= k;
            k <<= 1;
        }
        zeroonepack(num*v, num*val);
    }
    
    int main(){
        int n;
        while(scanf("%d %d", &n, &V)){
            if(!n && !V)  break;
            for(int i = 0; i < n; ++i)  scanf("%d", &a[i]);
            for(int i = 0; i < n; ++i)  scanf("%d", &c[i]);
    
            memset(d, 0, sizeof(d));
            for(int i = 0; i < n; ++i)
                multiplepack(a[i], a[i], c[i]);
    
            int cnt = 0;
            for(int i = 1; i <= V; ++i)
                if(d[i] == i)  ++cnt;
            printf("%d
    ", cnt);
        }
        return 0;
    }
    
  • 相关阅读:
    JOI2017FinalC JOIOI 王国
    JOISC2017C 手持ち花火
    P4336 [SHOI2016]黑暗前的幻想乡
    SP104 HIGH
    P3160 [CQOI2012]局部极小值
    P4965 薇尔莉特的打字机
    【BZOJ4361】isn
    P3506 [POI2010]MOT-Monotonicity 2
    P3214 [HNOI2011]卡农
    P3704 [SDOI2017]数字表格
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/5537556.html
Copyright © 2011-2022 走看看