小记:这里我是直接套用多重背包的模板直接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; }