有 N N N 种物品和一个容量是 V V V 的背包。
物品一共有三类:
- 第一类物品只能用1次(01背包);
- 第二类物品可以用无限次(完全背包);
- 第三类物品最多只能用 s i s_i si 次,每种体积是 v i v_i vi,价值是 w i w_i wi。(多重背包)
求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大.输出最大价值。
这个就算之前三种背包问题的综合问题了吧 (大概,可能,也许,应该,差不多)
在实际上,多重背包的问题就是01背包的拓展,那么就可以将多重背包转化为 l o g 2 S log_2S log2S 个01背包。将三种背包问题转化为两种最基本的背包。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#define MAX 1010
using namespace std;
typedef struct Thing
{
int v;
int w;
int s;
}Thing;
vector<Thing> things;
int f[MAX];
int N, V;
int main()
{
cin >> N >> V;
for (int i = 0; i < N; i++)
{
int v, w, s;
cin >> v >> w >> s;
if (s < 0)things.push_back({ v,w,-1 }); //01背包
else if (s == 0)things.push_back({ v,w,0 }); //完全背包
else //多重背包
{
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 });
}
} //将多重背包转化为01背包
}
for (auto thing : things)
{
if (thing.s < 0) //01背包当01背包做
{
for (int j = V; j >= thing.v; j--) f[j] = max(f[j], f[j - thing.v] + thing.w);
}
else //完全背包当完全背包做
{
for (int j = thing.v; j <= V; j++)f[j] = max(f[j], f[j - thing.v] + thing.w);
}
}
cout << f[V] << endl;
return 0;
}
对于背包问题的基本模型大概差不多了。后面就随缘去更了。。。