动态规划之01背包问题(最易理解的讲解)
来源:互联网 发布:java oracle 配置文件 编辑:程序博客网 时间:2024/04/29 11:36
转载地址: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的背包
以下是java的代码view plain copy
import java.util.Arrays;public class Package01 {public static void main(String[] args) {int wholeWeight = 10;PackageItem[] packageItems = init();int[][] result = get01PackageAnswer(packageItems, wholeWeight);for (int i = 0; i < result.length; i++) {System.out.println(Arrays.toString(result[i]));}}private static int[][] get01PackageAnswer(PackageItem[] packageItems, int wholeWeight) {int[][] matrix = new int[packageItems.length][wholeWeight + 1];//二位数组for (int i = 0; i < packageItems.length; i++) {//行PackageItem pi = packageItems[i];//要放进包的itemint piWeight = pi.weight;int piValue = pi.value;for (int j = 1; j <= wholeWeight; j++) {//列int bagSize = j;//当前背包的能承受的重量if (piWeight > bagSize) {//装不了//matrix[i][j] = matrix[i][j - 1];if (i ==0) {//如果是第0行matrix[i][j] = 0;} else {matrix[i][j] = matrix[i - 1][j];}} else {int weightDiff = bagSize - piWeight;//装入当前item,余下的重量if (i ==0) {//如果是第0行matrix[i][j] = piValue;} else {int valueInBag = matrix[i - 1][weightDiff] + piValue;//f[i-1,j-Wi]+Pi(j >= Wi)matrix[i][j] = valueInBag > matrix[i - 1][j] ? valueInBag : matrix[i - 1][j];}}}}return matrix;}static PackageItem[] init() {String[] nameArr = {"a","b","c","d","e"};int[] weightArr = {2,2,6,5,4};int[] valueArr = {6,3,5,4,6};PackageItem[] packageItems = new PackageItem[nameArr.length];for (int i = 0; i < nameArr.length; i++) {PackageItem pi = new PackageItem(nameArr[i], weightArr[i], valueArr[i]);packageItems[i] = pi;}return packageItems;}}class PackageItem { public String name; public int weight; public int value; public PackageItem(String name, int weight, int value) { this.name = name; this.weight = weight; this.value = value; } }
- 动态规划之01背包问题(最易理解的讲解)
- 动态规划之01背包问题(最易理解的讲解)
- 动态规划之01背包问题(最易理解的讲解)
- 动态规划之01背包问题(最易理解的讲解)
- 动态规划之01背包问题(最易理解的讲解)
- 动态规划之01背包问题(最易理解的讲解)
- 动态规划之01背包问题(最易理解的讲解)
- 动态规划之01背包问题(最易理解的讲解)
- 动态规划之01背包问题(最易理解的讲解)
- 动态规划之01背包问题(最易理解的讲解)
- 动态规划之01背包问题(最易理解的讲解)
- 动态规划—0-1背包问题(最易理解的讲解)
- 动态规划之01背包问题讲解
- 01背包问题(最易理解的讲解)
- 动态规划之背包问题,最基础的动态规划
- 动态规划之01背包问题 通俗理解动态规划的过程
- Java语言描述:回溯法之01背包问题(最易理解的回溯法讲解)
- 从01背包问题理解动态规划(看过最简单易懂的版本)
- sqlserver 转为varchar类型
- 大学毕业设计(web) 软件工程 / IT /网工孩子 做毕设
- Redis,SQLite,MySQL 与 Python
- 个人觉得比较好的网站、博客、文章
- 数据挖掘150道试题总结
- 动态规划之01背包问题(最易理解的讲解)
- java 向上转型
- Java里面本质都是值传递——别人写的表达不清楚,所以我写了下,方便初学者福利 也方便C语言思维的人理解。
- 51nodoj 1136 (容斥定理 || 欧拉函数)
- jquery 新建的元素事件绑定问题
- Android RecyclerView的使用
- 怎么查询交通银行卡的支付卡号?
- JavaScript-数组简记
- mongodb连接数引起响应时间变长