三种包的核心思想大同小异,即动态优化问题:
说明:
- f[j]表示:N件物品,背包容量j下的可容纳最大价值
- v[i]表示:第i件物品的体积
- w[i]表示:第i件物品的价值
- s[i]表示:对于多重包来说,dii件物品的数量
优化为一维状态下三个包的状态转移方程相同,均为:f[j] = max(f[j], f[j - v[i]] + w[i]
但其在二维对应的f[j]上表示的细节不同(此时f[j]可记作f[i][j])
- 01包的二维状态转移方程:f[i][j] = max(f[i - 1][j], f[i - 1][j - v[i]] + w[i]);
- 无限包的二维状态转移方程:f[i][j] = max(f[i][j],f[i-1][j-k*v[i]]+k*w[i]);//此状态转移方程以循环体的方式呈现在for(int k = 0 ; k*v[i]<=j ; k++){}中,来表示其中“无限”的含义
- 多重包的二维状态转移方程:f[i][j] = max(f[i - 1][j], f[i - 1][j - v[i]] + w[i]);//和01包相同,或者说多重包本身就是01包的变种(因为多重包就只是将多个01包整合在了一起,所以在处理模式上完全可以用循环遍历出所有的多重包countSumBags = sum(s[0],s[1],……),变成countSumbags个单纯的01包)
其中考虑的数据的污染带来的循环顺序的不同的问题,可以参看:
https://www.acwing.com/solution/content/1374/
输入说明:
第一行两个整数,N,V,用空格隔开,分别表示物品种数和背包容积。
接下来有 N 行,每行三个整数 vi,wi,si,用空格隔开,分别表示第 i 种物品的体积、价值和数量。
si=−1 表示第 i 种物品只能用1次;
si=0 表示第 i 种物品可以用无限次;
si>0 表示第 i 种物品可以使用 si 次;
#include <iostream>
using namespace std;
const int c = 1010;
int f[c];
struct bag{
int vi[c];
int wi[c];
int si;
int f[c];
}onlyBag, notLimitedBags, limitedBags;
int main(){
int N, V;
cin >> N >> V;
//建立三种情况下的包
for (int i = 1; i <= N; i++){
int v,w,s;
cin >> v >> w >> s;
if(s == -1){
onlyBag.vi[i] = v;
onlyBag.wi[i] = w;
onlyBag.si = s;
}
if(s == 0){
notLimitedBags.vi[i] = v;
notLimitedBags.wi[i] = w;
notLimitedBags.si = s;
}
else{
limitedBags.vi[i] = v;
limitedBags.wi[i] = w;
limitedBags.si = s;
}
}
//01包
for(int i = 1; i <= N; i++){
for (int j = V; j >= onlyBag.vi[i]; j--){
onlyBag.f[j] = max(onlyBag.f[j], onlyBag.f[j - onlyBag.vi[i]] + onlyBag.wi[i]);
}
}
//无限包
for(int i = 1; i <= N; i++){
for(int j = 0; j <= V; j++){
notLimitedBags.f[j] = max(notLimitedBags.f[j], notLimitedBags.f[j - notLimitedBags.vi[i]] + notLimitedBags.wi[i]);
}
}
//多重包
for (int i = 1; i <= N; i++){
for( int k = 0 ; k < limitedBags.si; k++)
{
for (int j = V; j >= limitedBags.vi[i]; j--){
limitedBags.f[j] = max(limitedBags.f[j], limitedBags.f[j - limitedBags.vi[i]] + limitedBags.wi[i]);
}
}
}
cout << onlyBag.f[V] << endl;//01包
cout << notLimitedBags.f[V] << endl;//无限包
cout << limitedBags.f[V] << endl;//多重包
}