题目来源acwing7
利用多重背包的二进制优化,可以将一种被扒皮分散为多个01背包,用三个a,b,c数组来记录转换之后的所有背包,c为bool型数组,如果为true,就是完全背包,false则为01背包,最后做一遍,以c的值分类。做完全背包和01背包
#include <iostream>
#include <cstdio>
using namespace std;
const int N = 1010, M = 10000;
int f[N], g[N];
int a[M], b[M];
bool c[M]; // false: 完全背包, true: 01背包
int n, m;
int main()
{
cin >> n >> m;
int inf = 0;
for (int i = 0; i < n; i ++)
{
int v, w, s;
scanf("%d%d%d", &v, &w, &s);
if(!s){
a[inf] = v;
b[inf ++] = w;
// c[inf ++] = s;
}
else
{
if(s == -1) s = 1;
int k = 1;
while(k <= s)
{
a[inf] = k * v;
c[inf] = 1;
b[inf ++] = k * w;
s -= k;
k <<= 1;
}
if(s)
{
a[inf] = s * v;
c[inf] = 1;
b[inf ++] = s * w;
}
}
}
for (int i = 0; i < inf; i ++)
{
if(c[i]){
for (int j = m; j >= a[i]; j --)
f[j] = max(f[j], f[j - a[i]] + b[i]);
}
else{
for (int j = a[i]; j <= m; j ++)
f[j] = max(f[j], f[j - a[i]] + b[i]);
}
}
cout << f[m] << endl;
return 0;
}
作者:Enchanted_77
链接:https://www.acwing.com/solution/content/12711/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。