背包模版整理
01背包:
题目描述:
有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。
第 i 件物品的体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。 输出最大价值。
#include <iostream>
using namespace std;
const int N=1e3+5;
int n,m;
int v[N],w[N];
int f[N];
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++){
scanf("%d%d",&v[i],&w[i]);
}
for (int i=1;i<=n;i++){
for (int j=m;j>=v[i];j--){
f[j]=max(f[j],f[j-v[i]]+w[i]);
}
}
printf("%d\n",f[m]);
return 0;
}
完全背包:
有 N 种物品和一个容量是 V 的背包,每种物品都有无限件可用。
第 i 种物品的体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。 输出最大价值。
#include <iostream>
#include <algorithm>
using namespace std;
const int N=1e3+5;
int n,m;
int v[N],w[N];
int f[N];
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++){
scanf("%d%d",&v[i],&w[i]);
}
for (int i=1;i<=n;i++){
for (int j=v[i];j<=m;j++){
f[j]=max(f[j],f[j-v[i]]+w[i]);
}
}
printf("%d\n",f[m]);
return 0;
}
多重背包:
有 N 种物品和一个容量是 V 的背包。
第 i 种物品最多有 si 件,每件体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。 输出最大价值。
#include <iostream>
#include <algorithm>
using namespace std;
const int N=1e2+5;
int n,m;
int f[N];
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++){
int v,w,s;
scanf("%d%d%d",&v,&w,&s);
for (int j=m;j>=0;j--){
for (int k=1;k<=s&&k*v<=j;k++){
f[j]=max(f[j],f[j-v*k]+w*k);
}
}
}
printf("%d\n",f[m]);
return 0;
}
混合背包:
有 N 种物品和一个容量是 V 的背包。
物品一共有三类:
第一类物品只能用1次(01背包); 第二类物品可以用无限次(完全背包); 第三类物品最多只能用 si 次(多重背包); 每种体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。 输出最大价值。
#include <iostream>
#include <algorithm>
using namespace std;
const int N=1005;
int n,m;
int v[N],w[N];
int f[N];
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++){
scanf("%d%d",&v[i],&w[i]);
int s;
scanf("%d",&s);
if (s==-1){
for (int j=m;j>=v[i];j--){
f[j]=max(f[j],f[j-v[i]]+w[i]);
}
} else if (s==0){
for (int j=v[i];j<=m;j++){
f[j]=max(f[j],f[j-v[i]]+w[i]);
}
} else {
for (int j=m;j>=0;j--){
for (int k=1;k<=s&&k*v[i]<=j;k++){
f[j]=max(f[j],f[j-v[i]*k]+w[i]*k);
}
}
}
}
printf("%d\n",f[m]);
return 0;
}
二维费用背包:
有 N 件物品和一个容量是 V 的背包,背包能承受的最大重量是 M。
每件物品只能用一次。体积是 vi,重量是 mi,价值是 wi。
求解将哪些物品装入背包,可使物品总体积不超过背包容量,总重量不超过背包可承受的最大重量,且价值总和最大。 输出最大价值。
#include <iostream>
#include <algorithm>
using namespace std;
const int N=1005;
int max_v,max_w;
int n;
int v[N],w[N],m[N];
int f[N][N];
int main(){
scanf("%d",&n);
scanf("%d%d",&max_v,&max_w);
for (int i=1;i<=n;i++){
scanf("%d%d%d",&v[i],&w[i],&m[i]);
}
for (int i=1;i<=n;i++){
for (int j=max_v;j>=v[i];j--){
for (int k=max_w;k>=w[i];k--){
f[j][k]=max(f[j][k],f[j-v[i]][k-w[i]]+m[i]);
}
}
}
printf("%d\n",f[max_v][max_w]);
return 0;
}
分组背包:
有 N 组物品和一个容量是 V 的背包。
每组物品有若干个,同一组内的物品最多只能选一个。
每件物品的体积是 vij,价值是 wij,其中 i 是组号,j 是组内编号。
求解将哪些物品装入背包,可使物品总体积不超过背包容量,且总价值最大。
输出最大价值。
#include <iostream>
using namespace std;
const int N=105;
int n,V;
int s[N];
int v[N][N],w[N][N];
int f[N];
int main(){
scanf("%d%d",&n,&V);
for (int i=1;i<=n;i++){
scanf("%d",&s[i]);
for (int j=1;j<=s[i];j++){
scanf("%d%d",&v[i][j],&w[i][j]);
}
}
for (int k=1;k<=n;k++){
for (int i=V;i>=0;i--){
for (int j=1;j<=s[k];j++){
if (i>=v[k][j]){
f[i]=max(f[i],f[i-v[k][j]]+w[k][j]);
}
}
}
}
printf("%d\n",f[V]);
return 0;
}