$\LARGE\color{orange}{刷题日记(算法提高课)}$
关于混合背包,我们可以通过物品可以选取的数量来进行分类讨论
若物品可以选择无限次,那么是完全背包;若物品可以选择有限次,那么是多重背包(01 背包可以看成特殊的多重背包)
因此对于单个物品而言,我们便按照这两种模型对应的方式处理
需要注意的是,多重背包的二进制优化可以不用额外数组来存储,直接多写一重循环就行,也就是枚举体积可以写在二进制循环当中
完整代码:
#include <iostream>
using namespace std;
const int N = 1010;
int f[N];
int n, m;
int main()
{
cin >> n >> m;
for(int i = 1; i <= n; i++)
{
int v, w, s;
cin >> v >> w >> s;
if(s == 0)//完全背包
{
for(int j = v; j <= m; j++)
f[j] = max(f[j], f[j - v] + w);
}
else//01背包或多重背包
{
if(s < 0) s = 1;
for(int k = 1; k <= s; k *= 2)
{
for(int j = m; j >= k * v; j--)//写在二进制优化里面
f[j] = max(f[j], f[j - k * v] + k * w);
s -= k;
}
if(s >= 0)
for(int j = m; j >= s * v; j--)
f[j] = max(f[j], f[j - s * v] + s * w);
}
}
cout << f[m] << endl;
return 0;
}