【题目描述】庆功会
为了庆贺班级在校运动会上取得全校第一名成绩,班主任决定开一场庆功会,为此拨款购买奖品犒劳运动员。期望拨款金额能购买最大价值的奖品,可以补充他们的精力和体力。
【输入】
第一行二个数n(n≤500),m(m≤6000),其中n代表希望购买的奖品的种数,m表示拨款金额。
接下来n行,每行3个数,v、w、s,分别表示第I种奖品的价格、价值(价格与价值是不同的概念)和能购买的最大数量(买0件到s件均可),其中v≤100,w≤1000,s≤10。
【输出】
一行:一个数,表示此次购买能获得的最大的价值(注意!不是价格)。
【输入样例】
5 1000
80 20 4
40 50 9
30 50 7
40 30 6
20 20 1
【输出样例】
1040
这是庆功会的代码: #include<bits/stdc++.h> using namespace std; int m,n,times[505],w[505],c[505],f[6010]; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d%d%d",&w[i],&c[i],×[i]); } for(int i=1;i<=n;i++) for(int k=times[i];k>0;k--)//有几个就重复取几次 for(int j=m;j>=w[i];j--)//从右到左是选一个 f[j]=max(f[j],f[j-w[i]]+c[i]);//取或不取找到大值 cout<<f[m]; }
这是混合背包的代码:
#include<bits/stdc++.h>
using namespace std;
//混合背包与庆功会极其相似,只改了m n的顺序,加了一个if语句
int m,n,times[505],w[505],c[505],f[6010];
int main()
{
scanf("%d%d",&m,&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&w[i],&c[i],×[i]);
if(!times[i]) times[i]=200;//如果是0,就取个最大的值
}
for(int i=1;i<=n;i++)
for(int k=times[i];k>0;k--)//有几个就重复取几次
for(int j=m;j>=w[i];j--)//从右到左是选一个
f[j]=max(f[j],f[j-w[i]]+c[i]);//取或不取找到大值
cout<<f[m];
}
【题目描述】混合背包
一个旅行者有一个最多能装V公斤的背包,现在有n件物品,它们的重量分别是W1,W2,...,Wn,它们的价值分别为C1,C2,...,Cn。有的物品只可以取一次(01背包),有的物品可以取无限次(完全背包),有的物品可以取的次数有一个上限(多重背包)。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
【输入】
第一行:二个整数,M(背包容量,M<=200),N(物品数量,N<=30);
第2..N+1行:每行三个整数Wi,Ci,Pi,前两个整数分别表示每个物品的重量,价值,第三个整数若为0,则说明此物品可以购买无数件,若为其他数字,则为此物品可购买的最多件数(Pi)。
【输出】
仅一行,一个数,表示最大总价值。
【输入样例】
10 3
2 1 0
3 3 1
4 5 4
【输出样例】
11
【提示】
选第一件物品1件和第三件物品2件。