题目大意
背包容量为v。现有n个物品,它们都有自己的重量和价值。
物品分成t组,每组最多选一个物品。
求背包能装下的最大价值。
输入
第一行:三个整数,v(背包容量,v<=200),n(物品数量,n<=30)和t(最大组号,t<=10);
第2…n+1行:每行三个整数wi,ci,p,表示每个物品的重量、价值、所属组号。
输出
仅一行,一个数,表示最大总价值。
思路
DP
首先,循环组别。
然后,循环背包的重量。
f[j]=重量小于等于j能获得的最大价值。
再循环组中的每一个。
f[j]=max(f[j],f[j-a[i][k]]+b[i][k]);
//a[i][k]为i组第k个物品的重量,b[i][j]为它的价值
代码
#include<cstdio>
#include<iostream>
using namespace std;
int v,n,t,a[11][11],b[11][11],c[11]={0},f[201]={0};
//c[组别]存该组别物品数量
//a[组别][第c[组别]个]存重量
//b[组别][第c[组别]个]存价值
//f[j]存重量小于等于j能获得的最大价值
void init(){ //输入
int zl,jz,zb;
scanf("%d%d%d",&v,&n,&t);
for(int i=1;i<=n;++i){
scanf("%d%d%d",&zl,&jz,&zb); //读入此物重量、价值、组别
a[zb][++c[zb]]=zl;
b[zb][c[zb]]=jz;
}
}
void work(){ //DP
for(int i=1;i<=t;++i) //循环组
for(int j=v;j>0;--j) //循环重量
for(int k=1;k<=c[i];++k) //循环组里第k个
{
if(j>=a[i][k]) //如果放得下
f[j]=max(f[j],f[j-a[i][k]]+b[i][k]); //比较原来的值和现在获得的价值
else continue; //不然就换下一个物品
}
}
int main(){
init(); //输入
work(); //DP
printf("%d",f[v]); //输出重量为v的最大价值
}