AcWing 7. 混合背包问题
原题链接
中等
作者:
不幸到吃土
,
2025-01-10 22:59:26
,
所有人可见
,
阅读 1
//将多重背包问题利用二进制优化转化为多个01背包问题,接着将所有物品按"01背包"和"完全背包"两类进行枚举
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 1010;
struct Thing{
int v,w;
int kind; //表示当前物品是哪一类物品
};
int f[N]; //一维空间优化版本
vector<Thing> things;
int main(){
int n,m;
cin >> n >> m;
//初始化背包问题
for(int i=0;i<n;i++){
int v,w,s;
cin >> v >> w >> s;
if(s == -1){ //若为01背包
things.push_back({v,w,-1});
}else if(s == 0){ //若为完全背包
things.push_back({v,w,0});
}else{ //若为多重背包,则利用二进制优化转化为多个01背包
for(int k=1;k<=s;k*=2){
s -= k;
things.push_back({v*k,w*k,-1});
}
if(s > 0){
things.push_back({v*s,w*s,-1});
}
}
}
for(auto i : things){
if(i.kind == -1){
for(int j=m;j>=i.v;j--) //01背包的优化:由大到小枚举
f[j] = max(f[j],f[j-i.v] + i.w);
}else{
for(int j=i.v;j<=m;j++) //完全背包的优化:由小到大枚举
f[j] = max(f[j],f[j-i.v] + i.w);
}
}
cout << f[m] << endl;
return 0;
}