hdu 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(dp多重背包)

小记:这里我是直接套用多重背包的模板直接A的,0/1,和完全背包还算记得,多重的之前记的是利用0/1和完全背包的2进制解法,现在记不太清了,码不出来,所以直接套了模板。


思路:多重背包,结合我blog里的一篇背包问题,和 多重背包解决的一个题目里的模板,即可A掉。


代码:( 0 ms)

#include <stdio.h>
#include <string.h>
#include <stack>
#include <iostream>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

const int MAX_ = 105;

int f[MAX_];
int price[MAX_];
int num[MAX_];
int weight[MAX_];

void ZeroOnePack(int cost,int weight,int V){
    int v;
    for(v = V; v >= cost; --v){
        if(f[v] < f[v - cost] + weight)
        f[v] =f[v - cost] + weight;
    }
}

void CompletePack(int cost,int weight,int V){
    int v;
    for(v = cost; v <= V; v++){
        if(f[v] < f[v - cost] + weight)
        f[v] =f[v - cost] + weight;
    }
}

void MultiplePack(int cost,int weight,int amount,int V){
    if(cost * amount >= V){
        CompletePack(cost,weight,V);return ;
    }
    int k = 1;
    while(k < amount){
        ZeroOnePack(k * cost,k * weight,V);
        amount -= k;
        k *=2;
    }
    ZeroOnePack(amount * cost,amount * weight,V);
}

int main() {
    int T;
    int n, m;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        for(int i = 0; i < m; ++i){
            scanf("%d%d%d",&price[i],&weight[i],&num[i]);
        }
        memset(f,0,sizeof(f));
        for(int i = 0; i < m; i++){
            if(num[i] > 1)
            MultiplePack(price[i],weight[i],num[i],n);
            else ZeroOnePack(price[i],weight[i],n);
        }
        int maxm = -1;
        for(int i = n; i > -1; --i){
            maxm = max(maxm,f[i]);
        }
        printf("%d\n",maxm);
    }
    return 0;
}


你可能感兴趣的:(hdu 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(dp多重背包))