背包问题
来源:互联网 发布:大量收购淘宝店铺 编辑:程序博客网 时间:2024/05/17 09:06
本文主要是结合以下两篇文章的理解
http://blog.csdn.net/kangroger/article/details/38864689
http://blog.csdn.net/mu399/article/details/7722810
问题:一个背包总容量为J(10),现在有I(5)个物品,第i个 物品体积为weight[i],价值为value[i],现在往背包里面装东西,怎么装能使背包的内物品价值最大?
也就是说可考虑的范围为I个物品,容量为J时背包能达到最大价值F(i,j)。那么对于第i个考虑的物品,它就存在着是否包含在这容量为J的包里的问题。(被考虑后才决定自身是否存在)
所以存在下面的转换公式:
F(i,j)=MAX{F(i-1,j),F(i-1,j-w[i])+v[i]} ------以下图第九列为例(j=9假定固定)
(1)F(i-1,j):是指i被考虑后,最终并不存在于最后的包里,因为只需要前i-1个在包里,就能达到现在把i个考虑进去的效果,如下图中value=10,从只有考虑e,d到包括c,其价值都没变,对于此时的value,c可以不需要。
下图的说明:
a:第五个物品;...... e:第一个物品,这张表是至底向上,从左到右生成的。为了叙述方便,用e2单元格表示e行2列的单元格,这个单元格的意义是用来表示只有考虑物品e时,有个承重为2的背包,那么这个背包的最大价值是0,因为e物品的重量是4,背包装不了。对于d2单元格,表示只有物品e,d时,承重为2的背包,所能装入的最大价值,仍然是0,因为物品e,d都不是这个背包能装的。
(2)F(i-1,j-w[i])+v[i]:是指只有当i被加到包里才能达到现在的效果,如上图10->15,a在前b,c,d,e基础上被考虑进去后,只有这第i个物品在包里,value值才能达到F(i,j)。那么在这种情况里,前i-1个物品的价值就应该扣除第i个物品所产生的效果的剩余部分:F(i-1,j-w[i]) ==》 F(5-1,9-w[5]) ==》 F(4,7)=9。
以上都是在考虑范围为(i,j)时,能够达到最大F(i,j)的可能,而两者中的最大者MAX符合。
以上是j固定的假设,其实j也是变化的,如公式,要得到F(i,j)必须由表格中的其他值来相加获得,最简单的办法就是把整个表格都求出来。
这个过程其实就是填充表格从左下到右上的逐渐递推,最后到F[I][J],即上图的15处(依据转换公式逐级...)
我们的目的是i=5,j=10,先将问题小化,从0,0开始(左下)》》i增加,j增加。
代码如下:
- #include<iostream>
- using namespace std;
- #define V 1500
- unsigned int f[10][V];//全局变量,自动初始化为0
- unsigned int weight[10];
- unsigned int value[10];
- #define max(x,y) (x)>(y)?(x):(y)
- int main()
- {
- int N,M;
- cin>>N;//物品个数
- cin>>M;//背包容量
- for (int i=1;i<=N; i++)
- {
- cin>>weight[i]>>value[i];
- }
- for (int i=1; i<=N; i++)
- for (int j=1; j<=M; j++)
- {
- if (weight[i]<=j)
- {
- f[i][j]=max(f[i-1][j],f[i-1][j-weight[i]]+value[i]);
- }
- else
- f[i][j]=f[i-1][j];
- }
- cout<<f[N][M]<<endl;//输出最优解
- }
因为这问题是先前大三下面试时遇到的(不会),现在的工作算法几乎也用不到,今天碰巧遇到,搁在心里难受,索性趁星期学习总结下,时间比较匆忙,但这是我目前对这个问题的最满意的理解,若有差错,请不吝赐教
- 【无限背包】背包问题
- 背包问题---01背包
- 背包问题--部分背包
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- Linux磁盘分区与挂载
- log4j配置讲解
- Eclipse中maven项目update project后项目编码会自动变成GBK的问题
- 根据字符串恢复IP问题
- ubuntu14.04 出现symbol lookup error
- 背包问题
- QSplitter在QTabWidget中使用
- 如何做出正确的选择
- Java中Math.round()方法原理解读
- js中函数对象的方法,原型方法apply、call、bind、toString、toLocaleString、valueOf
- to Gali
- myeclipse导入新工程后Ctrl+左键查看类源码失灵解决
- leetcode 140. Word Break II 动态规划DP + DFS深度优先搜索
- 洛谷 P1196 银河英雄传说