题目描述:有编号分别为1,2,3,4,5的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?

背包问题是典型的动态规划问题,也有一定的规律可循,通常采用自底向上的方式,先解决小问题,并存储,再解决大问题。

方法一:时间空间都为O(n^2)的解法,但可以得到最大价值情况下拿了哪些东西

这里dp[i][j]的含义是:在只有i个物品,最大容量为j时,能获得的最大价值

def bag(weight, value, max_W):N = len(weight)V = max_Wdp = [[0 for i in range(V+1)] for j in range(N+1)]for i in range(1,N+1):for j in range(1,V+1):if weight[i-1]<=j:dp[i][j] = max(dp[i-1][j],dp[i-1][j-weight[i-1]]+value[i-1])else:dp[i][j] = dp[i-1][j]for i in range(N+1):print(dp[i][:])return dpdef thing(weight,value,max_W,dp): # 找出具体选了那些物品,这个可以参考第一个链接N = len(weight)V = max_Wthing_flag = [0 for i in range(N)]j = Vfor i in range(N,0,-1):if dp[i][j] != dp[i-1][j]:thing_flag[i-1]=1j -= weight[i-1]print(thing_flag)weight = [2,2,6,5,4]
value = [6,3,5,4,6]
max_W = 10
dp = bag(weight, value, max_W)
thing(weight,value,max_W,dp)

这个例子中对应的dp矩阵如下所示

可以通过从右下角向上回溯得到所有拿了的物品,见thing函数。

图片参考自:https://blog.csdn.net/superzzx0920/article/details/72178544

方法二:时间为O(n^2),空间为O(2n)的解法

如果不需要求出具体选了哪些物品而只要最大价值,那在空间上还可以继续优化,因为我们求解dp[i]时,只用到了上一个子问题dp[i-1],所以存储两个一维数组即可。

def bag(weight, value, max_W):N = len(weight)V = max_Wdp = [0 for i in range(V)]dp_next = [0 for i in range(V)]for i in range(N):for j in range(V):if weight[i]<=j:dp_next[j] = max(dp[j],dp[j-weight[i]]+value[i])dp = dp_next.copy()    #注意这里要用.copy(),因为不用就是浅复制print(dp_next)return dp

方法三:时间为O(n^2),空间为O(n)的解法

再进一步思考,计算dp[i][j]时只使用了dp[i-1][0……j],没有使用dp[i-1][j+1]这样的话,我们先计算 j 的循环时,让j=V……1,即反方向计算,只使用一个一维数组即可。

def bag(weight, value, max_W):N = len(weight)V = max_Wdp = [0 for i in range(V)]for i in range(N):for j in range(V-1,-1,-1):if weight[i]<=j:dp[j] = max(dp[j],dp[j-weight[i]]+value[i])print(dp)return dp

背包问题-三种动态规划解法-逐步减少空间复杂度相关推荐

  1. 快排三种基本解法以及两种快排优化

    /*  快速排序  基本思想    选定每次排序的基准数据 在剩下的位置将小于基准值的数据放在基准值得左边,大于基准值的数据放到基准值的右边    一次划分之后 如果此基准值的左右两边仍存在大于两个数 ...

  2. (左神)数据结构与算法 ---- 判断链表是否为回文结构的三种高效解法

    链表在数据结构与算法中可谓"北斗之尊",现在让我们通过判断链表回文的小练习进一步更深地了解链表~ 文章目录 一.链表的节点结构 二.判断一个链表是否为回文结构 (一)解法1:将链表 ...

  3. 算法-连续项的最大和问题(最大子数组问题)三种不同解法

    连续项的最大和问题 (1)暴力求解 时间复杂度 O(n^2) (2)分治求解 时间复杂度 O(nlogn) (3) 线性求解 时间复杂度 O(n) C#代码 using System; using S ...

  4. 隐马尔科夫模型,第三种问题解法,维比特算法(biterbi) algorithm python代码

    上篇介绍了隐马尔科夫模型 本文给出关于问题3解决方法,并给出一个例子的python代码 回顾上文,问题3是什么, 下面给出,维比特算法(biterbi) algorithm 下面通过一个具体例子,来说 ...

  5. 0-1背包问题详解(DP分支限界回溯三种方法)

    0-1背包 将n个项目的权重和值,放入一个容量为W的背包中,得到背包中最大的总价值.换句话说,给定两个整数数组val[0..n - 1]和wt [0 . .n-1],分别表示与n个项目相关的值和权重. ...

  6. 背包问题动态规划解法

    一:题目: 背包问题 问题:两个数组 一个重量数组W 一个 价值数组 V 一个背包 bag  ,返回不超过背包容量返回最大价值 二:暴力解法 思路:暴力遍历,思路就是递归的时候 按 选或者不选 当前 ...

  7. 两数之和(JavaScript三种算法)

    给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出和为目标值 target  的那 两个整数,并返回它们的数组下标. 你可以假设每种输入只会对应一个答案.但是,数组中同一个 ...

  8. c语言中二叉树中总结点,C语言二叉树的三种遍历方式的实现及原理

    二叉树遍历分为三种:前序.中序.后序,其中序遍历最为重要.为啥叫这个名字?是根据根节点的顺序命名的. 比如上图正常的一个满节点,A:根节点.B:左节点.C:右节点,前序顺序是ABC(根节点排最先,然后 ...

  9. 搭上AI这趟车!用人工智能进行市场营销的三种方法

    全文共1815字,预计学习时长5分钟 图源:Google 随着人工智能的发展,没人想让自己的市场营销策略落后于人,尤其对于科技巨头和当代的初创企业来说.这就导致了一些令人费解的问题出现.其中一些问题包 ...

最新文章

  1. 《Redis官方文档》用Redis构建分布式锁
  2. Response.Redirect() 跳转中的ThreadAbortException
  3. 多个硬件体验如一,华为终端分布式技术会重构IoT生态吗?
  4. 【转】Azure DevOps —— Azure Board 之 长篇故事、特性、用户情景(故事)的用法应用场景
  5. es6一维数组转二维数组_技术图文:Numpy 一维数组 VS. Pandas Series
  6. oracle数据库密码复杂度查询,Oracle11g R2创建PASSWORD_VERIFY_FUNCTION对应密码复杂度验证函数步骤...
  7. 用Java描述数据结构之栈和队列,以及栈和队列的常用方法
  8. 动态污点分析——隐式流造成的漏报和误报
  9. leetcode题解776-旋转字符串
  10. 在LINUX系统中安装KVM虚拟化
  11. Atitit 输入法原理与概论ati use
  12. ios音视频开发路线及技术点
  13. Java实现微信扫一扫
  14. 关于集训7教机房没网络 问题的解决方案
  15. 小程序scroll-view,滚动到最低_小程序滚动到底部
  16. 科技云报道:FONE:半年融资过亿元,打造EPM领域“最强国货”
  17. GPA计算器beta1
  18. 三足鼎立写博赚钱之道--献给2010年初互联网扫黄运动被错杀的兄弟
  19. C++多线程技术--API
  20. genl_ops结构分析

热门文章

  1. H5+微信公众号扫二维码页面跳转功能 vue实现
  2. 淘系自研前端研发工具 AppWorks 正式发布
  3. vue2.0 webApp保存图片到相册
  4. 洛谷P1551 亲戚(并查集)
  5. Silverlight 教程第五部分:用 ListBox 和 DataBinding 显示列表数据 (木野狐译)
  6. 3D目标检测之数据集
  7. python-货币转换
  8. 程序复杂性度量方法-McCabe
  9. html静态网站中华传统文化网站主题设计 传统文化艺术耍牙15页
  10. C# 调用BarTender打印标签报错