01背包问题属于组合优化问题:假设你要出门旅游,你现在有一个书包,这个书包的容量(capacity)有限,有很多物品如牙刷、防晒霜、雨伞、水杯等等,但书包装不下所有物品,因此我们必须有所取舍。那么通常我们怎么取舍的呢?一般我们会选择那些重要的物品,这个重要性我们可以量化为一个数字(value)。此时背包问题就抽象为:

给定n个物品,容量为capacity的背包。每个物品自身体积ws=[w1, w2,w3...],每个物品的自身价值vs=[v1, v2, v3...],求书包在容量不超限的情况下,装入物品的最大价值是多少?(w1表示第一个物品的体积,v1表示第一个物品的价值)。

动态规划求解思想:问题可以由类似的子问题进行求解,定义数组形式来表示问题的解--->初始化数组的边界值--->递推求解整个数组值。

那么根据该思想,背包问题的动态规划思路建立过程如下

第一步:定义数组形式的问题解。定义dp[i][j],表示背包容量为j时,前i个物品能够组合出来的最大价值。先不考虑怎么推导,思考一下该定义下我们问题的最终解是什么???应当是dp[n][capacity], 即背包容量为capacity时,前n个物品的组合出来的最大价值。那么怎么想出来的要这么定义的呢?不同动态规划问题的数组定义方式不一样,如何定义数组也是最难的。根据个人经验,该数组定义时考虑控制问题规模的量,背包问题中是:物品个数可多些可少些,背包容量可大些可小些。我们说过动规是有子问题形式的,这个子问题隐藏着问题规模的变化,因此物品个数和背包容量控制着问题规模的变化,我们考虑用它们来表示背包问题的解。

第二步:初始化数组边界值。容易想到,dp[i][0],即背包容量为0时,前i个物品的最优价值一定是0,因为容量为0,说明没有物品能放入背包,那么背包价值为0。同样dp[0][j]=0,因为前0个物品的也没有价值。  此处需要注意一点:我们问题的最终解为dp[n][capacity], 在C++中,定义int dp[10],访问时只能访问到dp[9],因为数组下标从0开始。因此C++中定义形式是dp[n+1][capacity+1]

第三步:递推,简历动态规划方程。所有动规方程的建立都是考虑一点,数组形式下的dp[i][j]等于什么?即如何让已经求得的某些dp值来表示dp[i][j]。考虑dp[i][j]表示背包容量为 j 时,前i个物品的最优价值,对其求解时dp[i-1][j]是已知的,那么第 i 物品是否应该放入背包呢?第一种情况 i 物品的体积很大, 大于 j ,也即即便将背包里已有物品全挪走,i 物品也放不下背包中,此时dp[i][j] = dp[i-1][j]。                          第二种情况 i 物品体积比背包容量 j 小,也即如果背包可以腾出来 i 物品体积大小的地方,但是我们要想一下:要把i 放进去,会挪出来一部分物品,此时背包价值变为dp[i-1][j-wi]+vi, 即腾出来wi体积的地方后,剩余j-wi的地方放前i-1个物品的组合情况,然后该情况加上第i个物品价值即可。而如果我们不放入i物品,此时背包价值为dp[i-1][j],  因此最大的价值是dp[i][j]=max(dp[i-1][j-wi]+vi, dp[i-1][j])。

python代码如下:

# 第一行输入物品个数n和背包容量capacity
# 第二行输入物品体积w[]
# 第三行输入物品价值v[]
n, capacity = list(map(int, input().split()))
ws = list(map(int, input().split()))
vs = list(map(int, input().split()))ws = [0] + ws
vs = [0] + vs
dp = [[0]*(capacity+1) for i in range(n+1)] #dp[i][j]表示前i个物品,占据了j体积时的最优价值for i in range(1, n+1):for j in range(1, capacity+1):if ws[i]>j: #第i个物品放不下时,最优价值与前i-1个物品最优价值一致dp[i][j] = dp[i-1][j]else: #放得下时,因为要求放入i后剩余容量仍未j,那么势必有其他物品被取出,此时最大价值应考虑两部分:max(不放入i的最优价值,放i后的价值)dp[i][j] = max(dp[i-1][j], dp[i-1][j-ws[i]]+vs[i])print(dp[n][capacity])

01背包问题 动态规划求解方法 动态方程的详细解释 能理解的解释(附python代码)相关推荐

  1. 01背包问题—动态规划求解

    动态规划 01 背包问题 关键代码 for (int i = 1; i <= n; ++i){for (int j = 0; j <= c; ++j){if (j < w[i]) / ...

  2. 01背包问题 动态规划 java实现 简单通俗易懂

    ** 01背包问题 动态规划 ** 1.动态规划 什么是动态规划?动态规划就是将一个大问题不断向下拆分成小问题,直到拆分出的小问题可以求出其解,然后将小问题的解不断的向上合并,最终得到大问题的解决方案 ...

  3. 01背包问题动态规划(二维数组)

    01背包问题动态规划(二维数组) 问题描述 ​ 一个旅行者有一个最多能装 M 公斤的背包,现在有 n 件物品,它们的重量分别是W1,W2,-,Wn,它们的价值分别为C1,C2,-,Cn,求旅行者能获得 ...

  4. 0-1背包问题动态规划模型的Python解法

    0-1背包问题动态规划模型的Python解法 1.01背包问题 2.Python解决方案 3.01背包问题例题 1.01背包问题 背包问题(Knapsack problem)是一种组合优化的NP完全问 ...

  5. 背包问题动态规划matlab,01背包问题动态规划详解

    计算机算法分析考试:动态规划0-1背包问题,怎么算她说她没醉,却一直摇摇晃晃掉眼泪:你说你爱她,却从未想过给她一个家. 要考试了,老师给划重点有一题:动态规划0-1背包问题,怎么算. 怎么理问题描述: ...

  6. 【转】01背包问题动态规划详解

    转载自 sunstar1989 最终编辑 中华复生母 动态规划是用空间换时间的一种方法的抽象.其关键是发现子问题和记录其结果.然后利用这些结果减轻运算量. 比如01背包问题. 因为背包最大容量M未知. ...

  7. 算法设计与分析 0-1背包问题 动态规划解法【超详细】

    0-1背包问题 问题描述 给定i个物品和一个容量为的背包,物品的重量是Wi,其价值为Vi 物品个数为i,背包容量为C. 如何选择装入背包内的物品,使得装入背包中的物品的总价值最大? 其中,每种物品只有 ...

  8. 让你轻松搞懂0-1背包问题(动态规划 C语言版)

    题目描述 有n个物品,它们有各自的体积和价值,现有给定容量的背包,如何让背包里装入的物品具有最大的价值总和? 举一个例子: 有一个小偷他有一个容量为8的背包 物体的体积和价值如下所示: 物体编号 物体 ...

  9. 01背包问题——动态规划详解

    有N件物品和⼀个最多能被重量为W的背包.第i件物品的重量是weight[i],得到的价值是value[i].每件物品只能⽤⼀次,求解将哪些物品装入背包⾥物品价值总和最⼤. 在题目中我们假设有三件物品 ...

最新文章

  1. Apache+MySQL+PHP安装指南
  2. pthread调度策略,优先级和竞争范围
  3. Windows10 64位 安装 Postgresql 数据库
  4. 数组——寄包柜(洛谷 P3613)
  5. 深入理解 sudo 与 su 之间的区别【转】
  6. 服务器体系(SMP, NUMA, MPP)与共享存储器架构(UMA和NUMA)
  7. IOS中的多线程之GCD
  8. import和__import__()有什么不同?
  9. linux菜鸟要飞-根目录
  10. matlab手眼标定
  11. jsp遍历List map
  12. 个人微信支付宝接入GOGO支付免签系统详细教程(图文)
  13. 用iText把图片转成PDF
  14. 51单片机 数码管中断操作
  15. 【前端小实战】遮罩层动画效果
  16. 多线程编程 ----- 四种同步方法
  17. 会议邀请〡第六届全国高校电子信息类课程教学研讨会邀请函
  18. 嵩天-Python语言程序设计程序题--第五周:函数和代码复用
  19. 快速建站该怎么实现?
  20. 迅捷思维导图怎么画出来

热门文章

  1. java中设置基偶隔行换色_Excel2016中奇偶行填充不同颜色的方法
  2. numpy中axis理解
  3. windows如何获取端口号
  4. JS 逆向之 Hook
  5. 【106】360查字体-查询本地字体版权是否可商用
  6. 国产自研芯片取得的进展,连外媒都认可了,ARM真怕了
  7. 4.12 使用反相命令反转图片色彩 [原创Ps教程]
  8. Tableau参数:自定义周起始时间
  9. 虚拟路由器冗余协议(VRRP)
  10. 32位CPU最大支持4G内存