![](https://img-blog.csdnimg.cn/img_convert/ece617594d4cd1fb488b43c8bf9ac685.png)
一.题目分析:
假如我们有n组物品,背包的容量是m,然而每组物品我们只能选一种物品或者不选,但是总容量不能超过m,而且要总价值最大。
二.用集合的方式表示:
f[i,j]表示:n组物品中选,每组物品最多选一种或者不选,且总容量不能超过m的所有选法的集合。
三.计算集合:
我们所以做的事情就是在f[i,j]的所有子集中选出价值最大的那个子集。
(1)不选第i组的物品:
f[i,j]=max(f[i,j],f[i-1,j])
(2)选第i组的物品选第k个物品:
f[i,j]=max(f[i-1,j-v[i][k]]+w[i][k],f[i,j])
代码如下:
#include<iostream>
using namespace std;
const int N=110;
int n,m;
int f[N][N];
int s[N],v[N][N],w[N][N];
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>s[i];
for(int j=1;j<=s[i];j++)
cin>>v[i][j]>>w[i][j];
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
f[i][j]=f[i-1][j];
for(int k=1;k<=s[i];k++){
if(v[i][k]<=j)
f[i][j]=max(f[i-1][j-v[i][k]]+w[i][k],f[i][j]);
}
}
cout<<f[n][m];
return 0;
}