目录
题目
现在既给定了数量又要求每一类至多只能选选一个物品
这样一看又又类似于01背包问题了
因为对于f[i][j]它的更新方式就是对于f[i-1][j]进行更新 现在就是是否选择第i组物品中的某一个
于是乎相较于我们一开始的01背包差别就在于多了一个对第i组每个物品的遍历
代码
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=110;
int n,m;
int v[N][N],w[N][N],s[N];//表示第i组中每一个物品的体积和价值
int f[N];
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>s[i];
for(int j=0;j<s[i];j++)
cin>>v[i][j]>>w[i][j];
}
for (int i = 1; i <= n; i++)
for (int j = m; j >= 0; j--)//注意逆序,因为是从第i-1层更新而来
for (int k = 0; k < s[i]; k++)
if (v[i][k] <= j)
f[j] = max(f[j], f[j - v[i][k]] + w[i][k]);
cout<<f[m];
return 0;
}
小结
我们可以看到对于体积j是否要逆序取决的就是我们对集合的更新方式,即划分方式
如果它是从上一层更新而来就要逆序
如果是在自己这一层更新就不用逆序
题目来源acwing
模板来源:闫学灿
链接:https://www.acwing.com/activity/content/code/content/57785/
来源:AcWing