参考学习网址:
https://www.bilibili.com/video/av33930433?from=search&seid=10637513335818789097

https://www.cnblogs.com/anzhengyu/p/11408466.html

问题描述:
给定 n 件物品,物品的重量为 w[i],物品的价值为 v[i]。现挑选物品放入背包中,假定背包能承受的最大重量为 c,问应该如何选择装入背包中的物品,使得装入背包中物品的总价值最大?

思路:
刚开始接触到这个题目的想法是将单位价值最大次大…的几个物品依次装入背包(对单位价值的物品进行排序,从大到小),如果这个装不下就判断下一个是否能装入,直到判断完所有的物品,从而使背包中价值最大。可是这个做法只能通过一些测试,大部分测试通过不了。其实,这是一种贪心算法的思想,这种做法并不能保证背包最终被装满,这些剩余的空间就造成了价值的降低。贪心算法是一种只考虑局部最优的方法,而不是整体最优的方法,所以这个算法思想不是对所有问题都能求得整体最优解就比如这道01背包。

所以这里使用动态规划的思想,即不做重复运算,依次取出一件物品装入容量为1到c的背包,最终得到容量为c时能装入物品价值最大为多少。

我们只用考虑两种情况,装入和不装入。

这里dp[i][j]表示只看前i个物品,背包体积为j的情况下,总价值最大是多少。

不装入:如果在背包体积为j的情况下,不装入第i个物品,那么dp[i][j]就取之前背包体积为j的情况下,装入第i-1个物品时的最大价值,即dp[i-1][j]。
状态转移公式为:dp[i][j]=dp[i-1][j]

装入:在背包体积为j的情况下,如果装入第i个物品就需要与同背包体积时装入i-1个物品的最大价值做对比取最大值填入dp[i][j]。选取第i个物品时,总价值为装入的物品i的价值+背包还剩体积的最大价值。
状态转移公式为:dp[i-1][j-v[i-1]]+w[i-1] (遍历物品次数从1开始,价值体积索引-1)

n, c = map(int, input().split())
v_w = []
for i in range(n):v_w.append(list(map(int, input().split())))dp = [[0 for i in range(c+1)] for j in range(n+1)]for i in range(1, n+1):for j in range(1, c+1):dp[i][j] = dp[i-1][j]if j >= v_w[i-1][0]:dp[i][j] = max(dp[i][j], dp[i-1][j-v_w[i-1][0]]+v_w[i-1][1])print(dp[-1][-1])

以上代码就可以得到最优的01背包最大价值解,但是我们发现dp是用二维列表来存储最大价值,但我们只要背包容量为c时所能装的物品最大价值,这样就会造成很大的内存资源消耗。所以我们能不能将二维列表改为一维列表来存储最大价值呢?

通过上面的二维代码,可以发现dp[i]只与dp[i-1]有关。所以我们只需要让dp来存储上一次(选取物品i-1时)的最大价值。

由于在能装入的情况下,背包有剩余空间 (i-1),我们需要i-1体积时的最大价值,所以不能正向改变dp中的最大价值,这时候就需要倒着改变dp中的最大价值。

dp[i]表示背包容量为i时,选取多少物品得到的总价值最大是多少。

不装入:dp[i]=dp[i],在代码中可以省略

装入:和之前二维类似,dp[j-v[i-1]]+w[i-1]

n, c = map(int, input().split())
v_w = []
for i in range(n):v_w.append(list(map(int, input().split())))dp = [0 for i in range(c+1)]for i in range(n):for j in range(c, -1, -1):if j >= v_w[i][0]:dp[j] = max(dp[j], dp[j - v_w[i][0]] + v_w[i][1])print(dp[-1])

运行结果:

上面为二维运行结果,下面为一维运行结果。可以看出运行内存和时间均得到了优化。

运行测试网址:https://www.dotcpp.com/oj/problem1924.html

欢迎大家采纳和指正!!!
如果大家有更优的解法,欢迎在评论区留言。

dp 动态规划 01背包问题 Python相关推荐

  1. 代码随想录算法训练营day41 | 动态规划 01背包问题基础 01背包问题之滚动数组

    day41 01背包问题基础 问题描述 举个栗子 二维dp数组01背包 1.确定dp数组以及下标的含义 2.确定递推公式 3.dp数组如何初始化 4.确定遍历顺序 5.举例推导dp数组 01背包问题之 ...

  2. python实现动态规划0-1背包问题

    一.动态规划算法介绍 动态规划算法通常用于求解具有某种最优性质的问题.在这类问题中,可能会有许多可行解.每一个解都对应于一个值,我们希望找到具有最优值的解.动态规划算法与分治法类似,其基本思想也是将待 ...

  3. 动态规划——01背包问题 看此一篇文章就够了

    本文讲述经典算法--动态规划的 常见问题 01背包  一篇文章带你学会01背包问题,妈妈再也不担心我遇到01背包了!!! 问题描述 有n个物品,它们有各自的体积和价值,现有给定容量m的背包,如何让背包 ...

  4. 动态规划---01背包问题(2种方法)

    一.动态规划 代表一类问题(最优子结构或子问题最优性)的一般解法,是设计方法或者策略,不是具体算法 本质:递推,核心是找到状态转移的方式,写出dp方程. 解决问题:交叉,重叠子问题(最优子问题) 形式 ...

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

    代码随想录day42和day43 动态规划 模块01背包问题 "即使到不了远方,心中也要有远方的模样." 文章目录 1. 01背包理论基础 1.1什么是背包问题 1.2二维dp数组 ...

  6. 1.动态规划--01背包问题

    动态规划 DP问题思考时候分成两大部分考虑 1. 状态表示 f(i,j) (1) 集合:(所有选法的集合) 所有选法 条件: 1.从前i个物品中选 2. 总体积m<=j (2) 属性 最大值.最 ...

  7. 0-1背包问题python实现

    0-1背包问题 ACWings题目链接:https://www.acwing.com/problem/content/2/ 不会的小伙伴可以看一下视频:https://www.bilibili.com ...

  8. 动态规划-01背包问题

    大佬整理的理解链接:(建议先看一遍自行理解DP思想再去看代码) 动态规划之01背包问题 - kkbill - 博客园01背包问题 问题描述: 给定 n 件物品,物品的重量为 w[i],物品的价值为 c ...

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

    内容参考 https://blog.csdn.net/yoer77/article/details/70943462 https://labuladong.github.io/ebook/动态规划系列 ...

最新文章

  1. PowerDesigner与Rose详解教程
  2. linux io模拟时序,spi四种模式io模拟时序
  3. es中的AllocationService
  4. 盘点2013年那些最优秀的网页设计作品【系列五】
  5. 中国液冷数据中心发展白皮书
  6. 湖大计算机考研分数线,湖南大学2017年考研分数线已公布
  7. wamp php文件怎么创建数据库,phpmyadmin怎么创建数据库
  8. vi保存退出:x与:wq的区别
  9. 在linux中的文件中查找_如何在Linux中查找文件
  10. Python刷题-4
  11. python解不定积分_python快速求解不定积分和定积分
  12. GB/T 28181-2016与GB/T 28181-2011变更对比
  13. Openstack Fuel 9.0安装后网卡设置
  14. Matlab for循环subplot画图加标题
  15. 【Python-3.5】Pygal模拟骰子点数,分析结果可视化
  16. 垃圾分类:真正的麻烦在于怎样处理
  17. css中 background:0 0;
  18. 文件上传(FileUpload)
  19. CDA I级学习 - CDA I级报名
  20. 图书行业的两个术语:实洋、码洋

热门文章

  1. 大家应该知道的社保常识 看看吧会有用的
  2. 华为云devops认证考试课堂笔记3
  3. 数字化:从数字化转型到数字化经营:为什么、是什么、怎么做?
  4. iOS13 适配(持续更新中。。。)
  5. 我的vim配置文件(未完)
  6. 2019北京国际智能机器人展
  7. Oracle分组函数和筛选语句详析
  8. Vertx(Java版)Http的Get、Post请求(含有参数)及响应
  9. 用计算机上的窗口造句,窗口造句简单
  10. windows服务启动不了 错误1053