HDU 2844 Coins (多重背包问题DP)

Posted dwtfukgv

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n", cnt);
    }
    return 0;
}

 

以上是关于HDU 2844 Coins (多重背包问题DP)的主要内容,如果未能解决你的问题,请参考以下文章

HDU 2844 Coins (多重背包)

背包专题 D - Coins hdu2844多重背包

hdu2844Coins(多重背包模板)

hdu2844 Coins 多重背包

HDU 2844 Coins (多重背包计数 空间换时间)

背包系列练习( hdu 2844 Coins && hdu 2159 && poj 1170 Shopping Offers && hdu 3092