LintCode 背包问题
来源:互联网 发布:传奇一条龙源码 编辑:程序博客网 时间:2024/05/21 17:03
背包问题
注意事项
你不可以将物品进行切割。
如果有4个物品[2, 3, 5, 7]
如果背包的大小为11,可以选择[2, 3, 5]装入背包,最多可以装满10的空间。
如果背包的大小为12,可以选择[2, 3, 7]装入背包,最多可以装满12的空间。
函数需要返回最多能装满的空间大小。
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的背包
-------------------------------------------------------------华丽的分割线----------------------------------------------------------------------------------------------
本题由于没有物品价值这个维度,但是可以直接把物品的重量当做物品的价值,最后依然是求解出背包中最大价值的问题。
上面的解释中数组的更新是从底向上不是很直观,我们从上到下其实是一样的道理,二维数组result[A.size()][m+1] 中的result[i][j]表示在背包空间为j,有A中前i个物品可选的情况下,最大的价值是什么。
f[i,j] = Max{ f[i-1,j-Wi]+Pi( j >= Wi ), f[i-1,j] }
int backPack(int m, vector<int> A) {// write your code hereif (A.size() == 0)return 0;if (m == 0)return 0;vector<vector<int>> result(A.size(), vector<int>(m + 1, 0));for (int i = 0; i <= m; i++){if (i >= A[0])result[0][i] = A[0];}for (int i = 1; i < A.size(); i++){for (int j = 0; j <= m; j++){if (j - A[i] >= 0)result[i][j] = max(result[i - 1][j], result[i- 1][j - A[i]] + A[i]);elseresult[i][j] = result[i- 1][j];}}return result[A.size()][m];}
int backPack(int m, vector<int> A) {// write your code hereif (A.size() == 0)return 0;if (m == 0)return 0;vector<vector<int>> result(2, vector<int>(m + 1, 0)); //本来应该用二维数组存储,但是其实每一次计算只会用到上一行的数据,所以可以直接压缩到一个两行的数组for (int i = 0; i <= m; i++){if (i >= A[0])result[0][i] = A[0];}for (int i = 1; i < A.size(); i++){for (int j = 0; j <= m; j++){if (j - A[i] >= 0)result[i % 2][j] = max(result[abs(i % 2 - 1)][j], result[abs(i % 2 - 1)][j - A[i]] + A[i]);elseresult[i % 2][j] = result[abs(i % 2 - 1)][j];}}return result[A.size() % 2 == 0 ? 1 : 0][m];}
- LintCode-背包问题 II
- 【LintCode】Backpack 背包问题
- lintcode-背包问题-92
- LintCode : 背包问题 II
- LintCode :背包问题
- LintCode : 背包问题 II
- lintcode backpack 背包问题
- LintCode:背包问题
- LintCode:背包问题 II
- LintCode(M)背包问题
- LintCode:背包问题
- LintCode:01背包问题
- LintCode 62-背包问题
- LintCode 背包问题
- 背包问题-LintCode
- Lintcode 背包问题
- LintCode背包问题总结
- lintcode -- 背包问题
- 关于python安装环境的几个问题,mark一下
- 有哪些值得关注的技术博客(Java篇)
- Java概念性问题9
- 算法提高 超级玛丽
- POJ2100_Graveyard Design_尺取法::这样写更简洁
- LintCode 背包问题
- Linux学习-虚拟机安装Ubuntu
- eclipse的常用功能
- JavaScript中的对象(2)
- 将Servlet3.0版本的JavaWeb项目 回退到Servlet2.5版本
- 全球100个高质量Java开发者博客
- mevan pom.xml常见问题
- ES6优质文章汇总
- 纯CSS打造边框亮点移动效果