0-1背包问题

来源:互联网 发布:网页美工有前景吗 编辑:程序博客网 时间:2024/06/03 17:33

给定容量为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;}
原创粉丝点击