01背包问题,是用来介绍动态规划算法最经典的例子
来源:互联网 发布:mac sierra 双系统 编辑:程序博客网 时间:2024/09/21 09:03
转自:http://blog.csdn.net/mu399/article/details/7722810
01背包问题,是用来介绍动态规划算法最经典的例子,网上关于01背包问题的讲解也很多,我写这篇文章力争做到用最简单的方式,最少的公式把01背包问题讲解透彻。
01背包的状态转换方程 f[i,j] = Max{ f[i-1,j-Wi]+Pi( j >= Wi ), f[i-1,j] }
题目描述:
有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?
只要你能通过找规律手工填写出上面这张表就算理解了01背包的动态规划算法。
首先要明确这张表是至底向上,从左到右生成的。
为了叙述方便,用e2单元格表示e行2列的单元格,这个单元格的意义是用来表示只有物品e时,有个承重为2的背包,那么这个背包的最大价值是0,因为e物品的重量是4,背包装不了。
对于d2单元格,表示只有物品e,d时,承重为2的背包,所能装入的最大价值,仍然是0,因为物品e,d都不是这个背包能装的。
同理,c2=0,b2=3,a2=6。
对于承重为8的背包,a8=15,是怎么得出的呢?
根据01背包的状态转换方程,需要考察两个值,
一个是f[i-1,j],对于这个例子来说就是b8的值9,另一个是f[i-1,j-Wi]+Pi;
在这里,
f[i-1,j]表示我有一个承重为8的背包,当只有物品b,c,d,e四件可选时,这个背包能装入的最大价值
f[i-1,j-Wi]表示我有一个承重为6的背包(等于当前背包承重减去物品a的重量),当只有物品b,c,d,e四件可选时,这个背包能装入的最大价值
f[i-1,j-Wi]就是指单元格b6,值为9,Pi指的是a物品的价值,即6
由于f[i-1,j-Wi]+Pi = 9 + 6 = 15 大于f[i-1,j] = 9,所以物品a应该放入承重为8的背包
好,至此我们解决了背包问题中最基本的0/1背包问题。等等,这时你可能要问, 我现在只知道背包能装入宝石的最大价值,但我还不知道要往背包里装入哪些宝石啊。嗯, 好问题!让我们先定义一个数组x,对于其中的元素为1时表示对应编号的宝石放入背包, 为0则不放入。让我们回到上面的例子,对于体积为5,4,3,价值为20,10,12的3个宝石 ,如何求得其对应的数组x呢?(明显我们目测一下就知道x={1 0 1}, 但程序可目测不出来)OK,让我们还是从状态说起。如果我们把2号宝石放入了背包, 那么是不是也就意味着,前3个宝石放入背包的最大价值要比前2个宝石放入背包的价值大, 即:d(3, 10)>d(2, 10)。再用字母代替具体的数字 (不知不觉中我们就用了不完全归纳法哈),当d(i, j)>d(i-1, j)时,x(i-1)=1;j=j-w[i];OK,
int j=C-1;for(int i=N-1;i>0;i--){if(d[i][j]>d[i-1][j]){x[i]=1;j=j-w[i];}}if(d[0][j]>0)x[0]=1;
#include<iostream>using namespace std;const int N=5; const int C=10; int v[]={6,4,5,3,6},w[]={4,5,6,2,2};//下标从0开始 int x[N]; int d[N][C]={0};void find(){for(int j=0;j<C;j++){for(int i=0;i<N;i++){if(i==0){if(w[0]>j)d[0][j]=0;elsed[0][j]=v[0];}else if(j-w[i]<0)//剩余空间放不下当前的物品d[i][j]=d[i-1][j];elsed[i][j]=max(d[i-1][j],d[i-1][j-w[i]]+v[i]);}}}void main(){find();int j=C-1;for(int i=N-1;i>0;i--){if(d[i][j]>d[i-1][j]){x[i]=1;j=j-w[i];}}if(d[0][j]>0)x[0]=1;for(int i=0;i<N;i++){if(x[i]==1)cout<<i<<' ';}cout<<endl;cout<<d[N-1][C-1]<<endl;}
- 01背包问题,是用来介绍动态规划算法最经典的例子
- 01背包问题的动态规划算法
- 01背包问题 -- 经典动态规划题
- 动态规划经典问题:01背包
- 动态规划的两个经典问题--01背包
- 经典算法题04-动态规划算法(背包问题)
- 动态规划之背包问题,最基础的动态规划
- 0-1背包问题 动态规划 算法入门经典
- 背包问题的动态规划算法
- 动态规划算法之01背包问题
- 动态规划算法-解决01背包问题
- 算法面试---01背包问题---动态规划
- 动态规划算法之01背包问题
- 【算法】动态规划的用法——01背包问题
- 动态规划01背包例子
- 动态规划算法,背包问题
- 算法-动态规划-背包问题
- 动态规划的经典例子
- 奉化芋艿头
- POJ 1936 :All in All:简单字符串查找
- iOS点击空白处回收键盘
- objective c设计模式--通知中心
- 吐槽
- 01背包问题,是用来介绍动态规划算法最经典的例子
- Adapter模式实例
- 1045. Favorite Color Stripe (30)(BUG)
- 代码的第一印象(续):推荐几本经典书籍
- 光盘都无法识别解决方法
- Linux网络编程之socket:使用select函数实现并发处理
- 关于打开或重复加载Activity,ScrollView滚动条不在顶部,而在中间
- 区分JS中的undefined,null,"",0和false
- 浅谈cocos2d-x 的坐标体系