应用场景-背包问题

背包问题:有一个背包,容量为4磅 , 现有如下物品

  1. 要求达到的目标为装入的背包的总价值最大,并且重量不超出
  2. 要求装入的物品不能重复

动态规划算法介绍

  1. 动态规划(Dynamic Programming)算法的核心思想是:将大问题划分为小问题进行解决,从而一步步获取最优解的处理算法
  2. 动态规划算法与分治算法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。
  3. 与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。 ( 即下一个子阶段的求解是建立在上一个子阶段的解的基础上,进行进一步的求解 )
  4. 动态规划可以通过填表的方式来逐步推进,得到最优解.

思路分析和图解

  1. 背包问题主要是指一个给定容量的背包、若干具有一定价值和重量的物品,如何选择物品放入背包使物品的价值最大。其中又分01背包和完全背包(完全背包指的是:每种物品都有无限件可用)
  2. 这里的问题属于01背包,即每个物品最多放一个。而无限背包可以转化为01背包。
  3. 算法的主要思想,利用动态规划来解决。每次遍历到的第i个物品,根据w[i]和v[i]来确定是否需要将该物品放入背包中。即对于给定的n个物品,设v[i]、w[i]分别为第i个物品的价值和重量,C为背包的容量。再令v[i][j]表示在前i个物品中能够装入容量为j的背包中的最大价值。则我们有下面的结果:
    (1) v[i][0]=v[0][j]=0; //表示 填入表 第一行和第一列是0
    (2) 当w[i]> j 时:v[i][j]=v[i-1][j] // 当准备加入新增的商品的容量大于 当前背包的容量时,就直接使用上一个单元格的装入策略
    (3) 当j>=w[i]时: v[i][j]=max{v[i-1][j], v[i]+v[i-1][j-w[i]]}
    // 当 准备加入的新增的商品的容量小于等于当前背包的容量,
    // 装入的方式:
    v[i-1][j]: 就是上一个单元格的装入的最大值
    v[i] : 表示当前商品的价值
    v[i-1][j-w[i]] : 装入i-1商品,到剩余空间j-w[i]的最大值
    当j>=w[i]时: v[i][j]=max{v[i-1][j], v[i]+v[i-1][j-w[i]]} :

代码

package dynamic;public class KnapsackProblem {public static void main(String[] args) {int[] w = {1, 4, 3};  // 物品的重量int[] val = {1500, 3000, 2000};  // 物品的价值;这里的val[i] 就是v[i]int m = 4;  // 背包的容量int n = val.length; // 物品的个数// 创建二维数组// v[i][j] 表示前i个物品中能够装入容量为j的背包中的最大价值int[][] v = new int[n + 1][m + 1];// 为了记录放入商品的情况,定义一个二维数组int[][] path = new int[n + 1][m + 1];// 1. 初始化第一行第一列,这里在本程序中可以不处理(默认就是0)for (int i = 0; i < v.length; i++) {v[i][0] = 0;    // 将第一列设置为0}for (int i = 0; i < v[0].length; i++) {v[0][i] = 0;    // 将第一行设置为0}// 根据得到的公式来动态规划处理for (int i = 1; i < v.length; i++) {   // 不处理第一行 i是从1开始的for (int j = 1; j < v[0].length; j++) { // 不处理第一列 j是从1开始的// 公式if (w[i - 1] > j) { // 因为程序i从1开始,因此原来公式中w[i] 修改为w [i-1]v[i][j] = v[i - 1][j];} else { // 因为i从1开始,因此公式需要调整为以下代码//v[i][j] = Math.max(v[i - 1][j], (val[i - 1] + v[i - 1][j - w[i - 1]]));// 为了记录商品存放到背包的情况,不能简单地使用max公式,需要使用if-else-来体现公式if (v[i - 1][j] < (val[i - 1] + v[i - 1][j - w[i - 1]])) {v[i][j] = val[i - 1] + v[i - 1][j - w[i - 1]];// 记录最优情况path[i][j] = 1;} else {v[i][j] = v[i - 1][j];}}}}// 输出一下v看一下目前的情况printArrTwo(v);// 输出最后放入的哪些商品// 遍历path,会输出所有的放入情况,其实我们只需要最后一个/*for (int i = 0; i < path.length; i++) {for (int j = 0; j < path[i].length; j++) {if(path[i][j]==1){System.out.printf("第%d个商品放背包\n",i);}}}*/int i = path.length - 1;int j = path[0].length - 1;while (i > 0 && j > 0) { //从pth数组最后开始找if (path[i][j] == 1) {System.out.printf("第%d个商品放背包\n", i);j -= w[i - 1];}i--;}}/*** 遍历二维数组** @param v 二维数组*/public static void printArrTwo(int[][] v) {for (int i = 0; i < v.length; i++) {for (int j = 0; j < v[i].length; j++) {System.out.print(v[i][j] + " ");}System.out.println();}}
}

Java编程:动态规划相关推荐

  1. 西安尚学堂练习09.17|Java编程笔试面试题

    下列哪些类型能被throw语句抛出? A. Error B. Exception C. Throwable D. Object [解]注意Error也是可以被throw的,只是通常Error出现程序就 ...

  2. 除了java还学什么_学好Java编程除了努力还需要具备什么?

    Java编程语言的热流席卷了全球,它的出现摆脱了C语言尾大不掉的困境,灵活.多变,塑造性强的特点不仅符合当下互联网的发展趋势,也得到一批批青年俊才的青睐,Java编程抛出的橄榄枝,也吸引了大量计算机专 ...

  3. 偏执却管用的 10 条 Java 编程技巧

    经过一段时间的编码(咦,我已经经历了将近20年的编程生涯,快乐的日子总是过得很快),我们开始感谢那些好习惯.因为,你知道- "任何可能出错的事情,最后都会出错." 这就是人们为什么 ...

  4. 学习Java编程培训的书籍有哪些

    学习java技术除了线上线下的培训学习,书籍的知识也是非常重要的,今天小编为大家整理的就是学习Java的一些书籍,Java书籍是程序员学习提升技能的重要学习渠道,通过书籍Java程序员可以学习当前流行 ...

  5. Java编程的逻辑 (39) - 剖析LinkedList

    本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...

  6. 某程序员吐槽:免费教妹子Java编程,妹子却不让自己找她闲聊!

    许多程序员教妹子编程.带妹子打游戏,都是醉翁之意不在酒,名为教学,实为追求,但有一个程序员小哥哥却比较悲催,他答应一个妹子当她师傅,教她Java编程,结果妹子却说,学习是学习,平时是平时,让小哥哥平时 ...

  7. Java 编程技巧之数据结构

    Photo @markusspiske 文 | 常意 导读 唐宋八大家之一欧阳修在<卖油翁>中写道: 翁取一葫芦置于地,以钱覆其口,徐以杓酌油沥之,自钱孔入,而钱不湿.因曰:"我 ...

  8. java开发编程周末班_今天,Java编程周末提高班(第一期)正式结束

    Java编程周末提高班(第一期),走过了近两个月历程,一共同拥有68人次学生周末到老师家进行Java学习与交流.近距离的和一群年轻的学习接触,收获非常多,特别是对以后教学的改进.在学习的闲暇.大家自己 ...

  9. jar java classpath_win7中java编程工具安装 java环境变量设置

    win7中java编程工具安装 java环境变量设置 Question:编译是显示'javac'不是内部或外部命令,也不是可运行的程序或批处理文件 解决: 在[系统变量]里编辑java_home.cl ...

  10. Java编程笔试时输入问题:如何输入固定长度、不定长度的一维数组?如何输入固定长度、不定长度的二维数组?

    Java编程笔试时输入问题: 如何输入固定长度.不定长度的一维数组? 如何输入固定长度.不定长度的二维数组? 如何将数组中的内容直接输出,不要中括号和逗号? 文章目录 ==Java编程笔试时输入问题= ...

最新文章

  1. ulimit -n 修改
  2. python 学习笔记day03-python基础、python对象、数字、函数
  3. spring代码异常捕获到logback logging.config=logback-spring.xml文件中不能输出异常e.printStackTrace...
  4. .bat文件该图标_电脑桌面图标变成白色方块图标怎么办?
  5. .NET开发者如何使用MyCat
  6. Python第十七课(面向对象基础)
  7. ignite通过注解配置查询
  8. 不要解决:如何将JavaScript集合与目标相匹配
  9. SVN创建分支与分支合并主干
  10. 基于灰狼优化算法的线性规划问题求解matlab程序
  11. layui后台管理系统 - 权限树表格
  12. 7天刷完剑指offer(一)
  13. Python爬取京东图书销量榜
  14. 怎么读取cf卡id_CF卡传输程序的步骤解析
  15. 2022年QQ微信内置浏览器 UA 标识, Header 获取
  16. 【寒江雪】Go实现模版方法模式
  17. vs2015下载路径
  18. Rplot函数图形参数设置
  19. BootStrap Table:列参数
  20. 学校学业水平测试软件,中小学生学业水平测试

热门文章

  1. 10.Doctrine2 (2)
  2. 5. soapui 测试
  3. 3.4 Zend_Db_Table_Row
  4. python if else格式_Python进阶之路 3.4.2 条件语句(if、else和elif)
  5. 详解MySQL的用户密码过期功能
  6. ubuntu16.04安装中文输入法
  7. 【Tyvj】1473校门外的树3 线段树/树状数组 区间修改+单点访问
  8. ASP.NET之Response.Write说
  9. 微信小程序——尤克里里和弦查询
  10. Node.js格式化输出json文件