给定容量为c的背包和n个物品,每个物品的重量为wi,每个物品的价值为vi。
应该如何选择装入背包的物品,让背包所能获得最大价值。
0-1背包问题的状态转移方程为f[i][j]=max{ f[i-1][j] , f[i-1][j-w[i]]+v[i]}
声明一个大小为f[n][c]的二维数组,f[i][j]表示在面对物品i时,前i-1件物品,在容量为j的背包里,所能获得的最大价值
二维数组的计算方法如下:
j < w[i] 表示背包容量装不下物品i,只能不拿,则f[i][j]=f[i-1][j]
j >= w[i] 表示背包容量可以放下第 i 件物品,我们就要考虑拿这件物品是否能获取更大的价值
如果取第i件物品,就要f[i][j]=f[i-1][j-w[i]]+v[i],表示装了第i件物品,背包的容量就要减少w[i],但是价值增加了v[i]
如果不取第i件物品,就要f[i][j]=f[i-1][j],表示不装第i件物品,背包的最大价值还是f[i-1][j]
取还是不取就要决定于max{ f[i-1][j] , f[i-1][j-w[i]]+v[i]}
如下四个物品,容量为8的背包
推算过程
代码实现
#include<iostream>
#include<cstring>
using namespace std;
int main(){
int v[5]={0,3,4,5,6};
int w[5]={0,2,3,4,5};
int c=8;
int f[5][11];
memset(f,0,sizeof(f));
for(int i=1;i<=5;i++){
for(int j=1;j<=c;j++){
if(j<w[i]){
f[i][j]=f[i-1][j];
}
else{
f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+v[i]);
}
}
}
for(int i=1;i<=5;i++){
for(int j=1;j<=c;j++){
cout<<f[i][j]<<" ";
}
cout<<endl;
}
return 0;
}