一、01背包问题描述

有n 个物品,它们有各自的重量和价值,现有给定容量的背包,如何让背包里装入的物品具有最大的价值总和?

i

1

2

3

4

w(体积)

2

3

4

5

v(价值)

3

4

5

6

二、解法分析

1.分层考虑解决"每个物品最多只能装一次"

每个物品只能装一次,那么就应该想到常用的一种方法,就是用数组的纵轴来解决,对于n个物品,为它赋予i=1~n的编号,那么数组的纵轴就有n层,每层只考虑装不装这个物品,那么分层考虑就可以解决最多装一个的问题了。

2.对0,1的理解

  • 对于每个背包,都只有0和1的情况,也就是拿或者不拿两种情况。
  • 如果拿:那么空间就会减一点,比如说现在在考虑第i个物品拿不拿,如果说当前剩余空间为j,那么拿了之后空间就变为j-c[i],但是总价值却会增加一点,也就是增加w[i]。
  • 如果不拿:那么空间不会变,还是j,但是总价值也不会变化。

3.限制条件

所以对于这题来说有一个限制条件,就是空间不超出,然后目标就是在空间不超出的情况塞入物品使总价值最大。

本问题中最重要的两个值就是物品、背包重量。

4.递归方程的推导

所以定义:m[i][j]表示编号为i的物品、当背包容量为j时的最大可容纳价值。

递归方程:

  1. 当w[i] > j的时候,说明放不下去,所以肯定不能放i号物品,所以:m[i][j] = m[i-1][j]
  2. 当w[i] <= j的时候,说明放的下去,那么问题就是放不放,如果放的话价值是m[i-1][j-w[i]] + v[i];如果不放下去,就是m[i][j] = m[i-1][j]。所以放不放显然取决于两个值的大小。

综上,得到递归方程:

if(j>=w[i])m[i][j]=max(m[i-1][j],m[i-1][j-w[i]]+v[i]);
else  m[i][j]=m[i-1][j];  

因为这里涉及m[i-1][j],所以递推需要把m[0][j]算出来,然后从1开始递推。m[0][j]比较简单,就是比较w[0]和j的关系。

三、代码实现

/**** @param w 物品i的重量为wi* @param v 物品i的价值为vi* @param c 背包总的容量为c* @return 能装入背包的总价值*/
public static int getResult(int w[], int v[], int c) {if(w.length != v.length) {throw new IllegalArgumentException();}if (c <= 0) {return 0;}int n = w.length;//m[i][j] 表示 在背包容量剩余j的时候考虑到第i件物品的最大价值(i从0还是计数)int m[][] = new int[n][c + 1];for(int j = 0; j < c + 1; j++) {if(w[0] > j) {m[0][j] = 0;} else {m[0][j] = v[0];}}for(int i = 1; i < n; i++) {for(int j = 0; j < c + 1; j++) {if(w[i] > j) {m[i][j] = m[i - 1][j];} else {m[i][j] = Math.max(m[i - 1][j], m[i - 1][j - w[i]] + v[i]);}}}return m[n - 1][c];
}

四、总结

对于01背包问题,用蛮力法与用动态规划解决得到的最优解和解组成是一致的,所以动态规划解决此类问题是可行的。动态规划效率为线性,蛮力法效率为指数型,结合以上内容和理论知识可以得出,解决此问题用动态规划比用蛮力法适合得多。对于动态规划不足的是空间开销大,数据的存储得用到二维数组;好的是,当前问题的解只与上一层的子问题的解相关,所以,可以把动态规划的空间进行优化,使得空间效率从O(n*c)转化为O(c),遗憾的是,虽然优化了空间,但优化后只能求出最优解,解组成的探索方式在该方法运行的时候已经被破坏掉;总之动态规划和优化后的动态规划各有优缺点,可以根据实际问题的需求选择不同的方式。


我的微信公众号:架构真经(id:gentoo666),分享Java干货,高并发编程,热门技术教程,微服务及分布式技术,架构设计,区块链技术,人工智能,大数据,Java面试题,以及前沿热门资讯等。每日更新哦!

参考资料:

  1. https://www.jianshu.com/p/cb5957344256
  2. https://www.cnblogs.com/Christal-R/p/Dynamic_programming.html
  3. https://www.cnblogs.com/zyacmer/p/9961710.html
  4. https://www.jianshu.com/p/b0376bc3cd76

程序员的算法课(7)-01背包问题相关推荐

  1. 视频教程-程序员必备算法课!(揭秘淘宝购物车算法)-机器学习

    程序员必备算法课!(揭秘淘宝购物车算法) CSDN讲师名下集合了诸多业界知名讲师的公开课内容,内容涵盖人工智能.大数据.区块链等诸多热门技术领域的最佳技术实践,聚合美团.滴滴.AWS.科大讯飞等知名企 ...

  2. 程序员的算法课(5)-动态规划算法

    前言 众所周知,递归算法时间复杂度很高为(2^n),而动态规划算法也能够解决此类问题,动态规划的算法的时间复杂度为(n^2).动态规划算法是以空间置换时间的解决方式. 一.什么是动态规划 动态规划(D ...

  3. 程序员的算法课(4)-二分查找

    一个90%的程序员写不对的程序,一个面试高频出现的面试题,一个开发中用之甚广的算法,一个最能体现程序员素质的代码,它就是二分查找. 一.二分查找的定义 [百度百科]二分查找也称折半查找(Binary ...

  4. 哈夫曼编码压缩率计算_程序员的算法课(8)-贪心算法:理解霍夫曼编码

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_37609579/article/ ...

  5. 程序员的算法课(8)-贪心算法:理解霍夫曼编码

    一.一种很贪婪的算法定义 贪心是人类自带的能力,贪心算法是在贪心决策上进行统筹规划的统称. [百度百科]贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体 ...

  6. 程序员的算法课(3)-递归(recursion)算法

    一.什么是递归 递归是一种数学上分而自治的思想. 递归将大型复杂问题转化为与原问题相同但规模较小 的问题进行处理 递归需要有边界条件,当边界条件不满足时,递归继续进行:当边界条件满足时,递归停止 [百 ...

  7. 程序员的算法课(1)-算法概述

    [算法之美]数据结构+算法=程序. 前言 数据结构只是静态的描述了数据元素之间的关系.高效的程序需要在数据结构的基础上设计和选择算法. 高效的程序=恰当的数据结构+合适的算法 算法(Algorithm ...

  8. c 递归下降识别程序_程序员的算法课(3)-递归(recursion)算法

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_37609579/article/ ...

  9. 程序员的算法课(20)-常用的图算法:最小生成树(MST)

    一.图的生成树和最小生成树 生成树(SpanningTree):如果一个图的子图是一个包含图所有节点的树,那这个子图就称为生成树.图的生成树不惟一.从不同的顶点出发进行遍历,可以得到不同的生成树.专业 ...

最新文章

  1. Nat. Med.:iHMP之“微生物组与早产”
  2. JSONP的原理与实现(基于jQuery)
  3. (转)基本光照模型公式
  4. java正方形个圆形面积_java计算图形面积(圆形,正方形, 长方形).pptx
  5. huffman算法c语言程序,哈夫曼算法构造代码
  6. 【Oracle】设置快速恢复区及reset快速恢复区
  7. C++语言基础 例程 命名空间要解决的问题
  8. 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_09 序列化流_6_练习_序列化集合...
  9. 使用C++编写一个DHT爬虫,实现从DHT网络爬取BT种子
  10. matlab中plot3,mesh,grid三者画图的区别
  11. 单片机技术应用实训考核,AT89S52单片机应用教学,QY-KC20
  12. [深度学习概念]·深度学习的人脸识别技术发展综述
  13. 微信商户平台所有产品总结
  14. 罗永浩发声:我的努力很可能失败 但好产品一定要赢
  15. 认证的服务号可以快速注册并认证小程序,但是有额度限制
  16. Python学习笔记---sep用法
  17. 安全架构--8--我设计的企业安全体系架构
  18. 汉字文化杂志汉字文化杂志社汉字文化编辑部2022年第11期目录
  19. 在线打包app平台以及流程平台分析(AndroidiOS)
  20. 优衣库推全新门店概念,背后意义何在?

热门文章

  1. 关于研究网站开发还是应用程序的思考
  2. 在asp.net中使用线程
  3. 微信小程序图片上下有等值空白问题
  4. mysql的几种模式_MYSQL复制的几种模式
  5. 【Linux系统和服务管理】MySQL服务器安装与配置(一)
  6. 【MyBatis框架】mybatis逆向工程自动生成代码
  7. 面试中的 10 大排序算法总结
  8. python设计模式13-责任链模式
  9. IPv6下网络编程实例
  10. Laravel源码解析之中间件