应用场景-背包问题

背包问题:有一个背包,容量为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. 《The Sixth Sense》(《灵异第六感》)观后
  2. “智慧城市”背后的安全隐患
  3. DFS--POJ 1190 生日蛋糕
  4. 牛客题霸 [合并两个有序的数组] C++题解/答案
  5. php fastcgi exp,nginx +phpfastcgi 环境下 导出excel文件,超时,数据被截断问题,解决...
  6. CKeditor自定义上传图片功能
  7. 一个程序员的逗逼瞬间(二)
  8. Java 表达式解析(非原创)
  9. mysql独立开发_nacos的mysql独立部署
  10. [Python+debug] 设置Python环境变量-Windows10
  11. pandas处理mysql 展现wpf_Pandas DataFrame使用多列聚合函数
  12. IT程序猿应该投资些什么
  13. REST(三)Restlet实现REST
  14. (一)双目标定OpenCV读双目摄像头合并图像并分割
  15. hbase基本操作命令及练习
  16. 2022年最流行的几款软件缺陷管理工具
  17. vue2.0 使用可选链操作符
  18. 陶泓达:最新黄金,原油短线交易策略!
  19. iOS个推消息推送的使用
  20. css的文本省略号(单行和多行)

热门文章

  1. 9. grouped product
  2. 20. jQuery 遍历 - 祖先
  3. 1. 正则表达式简介
  4. html5中drag//drop拖曳效果的用法
  5. Parse Server(含Dashboard)部署于Centos7.6 64位
  6. 【转载】 C#使用Newtonsoft.Json组件来反序列化字符串为对象
  7. 0/1背包总结(持续更新...)
  8. hdu 6129 Just do it
  9. SEAYAR - 思雅,快乐生活
  10. [备查]SPQuery 返回所有的项目(查询不生效)的问题