珍惜现在, 感恩生活,记得汶川大地震那年我还在6年级, 当时以为是后面的同学在摇我的凳子, 几分钟后班里机智的同学才说地震了,大家赶快往楼下跑。这道题才让我真正理解了背包九讲前面讲解的东西, 题意就不赘述了。很传统的多重背包的题,多重背包代码如下:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int inf = 0x3f3f3f3f; int n, m; //金额 大米种类 int p[100+10], h[100+10], c[100+10]; //价格 重量 袋数 int f[100 + 10]; //大米的价格为f时 重量的最大值 void CompPack(int cost, int weight) { for(int j=cost; j<=n; j++) if(f[j]<f[j-cost]+weight && f[j-cost]>=0) f[j] = f[j-cost] + weight; return ; } void ZeroOnePack(int cost, int weight) { for(int j=n; j>=cost; j--) if(f[j]<f[j-cost]+weight && f[j-cost]>=0) f[j] = f[j-cost] + weight; return ; } void multipack(int cost, int weight, int number) { if(cost*number > n) { CompPack(cost, weight); return ; } int k = 1; while(k < number) { ZeroOnePack(k*cost, k*weight); number -= k; k *= 2; } ZeroOnePack(number*cost, number*weight); } int main() { int T; scanf("%d", &T); while(T--) { scanf("%d%d", &n, &m); for(int i=0; i<m; i++) scanf("%d%d%d", &p[i], &h[i], &c[i]); for(int i=0; i<=n; i++) f[i] = -inf; f[0] = 0; for(int i=0; i<m; i++) multipack(p[i], h[i], c[i]); printf("%d ", f[n]); } return 0; }
下面是01暴力背包 大体思路就是将一种物品看成好几个物品分别做01背包
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int inf = 0x3f3f3f3f; int n, m; //总钱数 和 大米的种类数、 int p[100+10], h[100+10], c[100+10]; //大米的单价 大米的重量 以及数量 int f[100 + 10]; //价钱为j时的最大重量 void ZeroOnePack(int cost, int weight) { for(int j=n; j>=cost; j--) if(f[j]<f[j-cost]+weight && f[j-cost]>=0) f[j] = f[j-cost] + weight; return ; } int main() { int T; scanf("%d", &T); while(T--) { scanf("%d%d", &n, &m); for(int i=0; i<m; i++) scanf("%d%d%d", &p[i], &h[i], &c[i]); for(int i=0; i<=n; i++) f[i] = -inf; f[0] = 0; for(int i=0; i<m; i++) for(int j=0; j<c[i]; j++) ZeroOnePack(p[i], h[i]); printf("%d ", f[n]); } return 0; }