动态规划背包问题优化空间复杂度——滚动数组

  • 背包问题
  • 空间复杂度优化
  • Java代码

链接:代码随想录背包问题

背包问题

  背包问题是动态规划中基本的问题,我们考虑下面的简单问题:

  假设背包容量为4,有物品0,1,2,要使背包放的物品价值最大,并且总重量不超过背包容量,应该怎么放?
二维数组下的做法如下:
1、创建二维数组dp,其中dp[i][j]的含义是在0~i物品中任意取,放到容量为j的背包里,能够获得的最大价值。
2、确定递推公式
对于dp[i][j],假设不取第i个物品,那么dp[i][j]=dp[i-1][j];假设取第i的物品,那么dp[i][j]=dp[i-1][j-weight[i]]+value[i]。为了获得更大的物品价值,dp[i][j]要取两者的最大值,即递推公式为:

dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i])

3、初始化dp数组
背包容量为0时,对于j=0时,dp[i][0]=0;对于i=0时,只有当j>=weight[i]时,dp[0][j]=0。在这个例子中初始化dp如下:

4、确定遍历顺序
可以先遍历背包,再遍历物品,也可以先遍历物品,再遍历背包。
5、举例推导dp数组

注意:做动态规划时,最好把dp能写出来,遇到有报错可以打印dp数组进行对比,看哪里出错。

空间复杂度优化

  二维数组可以优化成一维数组,即将一个一维数组重复利用,称之为滚动数组。只保留一个和背包容量+1的一维数组,遍历物品,对每个物品,更新这个一维数组,由上面的递推公式,dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]),可以改写成dp[i][j] = max(dp[i][j], dp[i][j - weight[i]] + value[i]),相当于更新dp[i][j]前,它表示上一层的dp[i-1][j],更新后,它表示dp[i][j]。而如果我们从小容量背包到大容量背包遍历,会出现前面小容量的背包不再是上一层的dp,而是已经更新过的dp,因此这样遍历会出现重复计算物品的现象。因此对于背包应该从大背包向小背包遍历。五部曲分析:
1、确定dp和含义,dp是长度和背包长度+1的一维数组,dp[j]表示容量为j的背包能装的最大物品价值
2、确定递推公式
dp[j] = max(dp[j], dp[j - weight[i]] + value[i])
3、dp数组初始化
由于dp[j]代表容量为1的背包装的最大物品价值,因此j=0时dp[0]=0,其余情况也可以赋dp[j]=0,因为后面会将dp[j]覆盖。
4、遍历顺序
只能从后往前遍历,即从大背包向小背包遍历,防止之前的数据被覆盖。
5、举例推导dp数组

Java代码

public static void main(String[] args) {int[] weight = {1, 3, 4};int[] value = {15, 20, 30};int bagWight = 4;testWeightBagProblem(weight, value, bagWight);
}public static void testWeightBagProblem(int[] weight, int[] value, int bagWeight){int wLen = weight.length;//定义dp数组:dp[j]表示背包容量为j时,能获得的最大价值int[] dp = new int[bagWeight + 1];//遍历顺序:先遍历物品,再遍历背包容量for (int i = 0; i < wLen; i++){for (int j = bagWeight; j >= weight[i]; j--){dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);}}//打印dp数组for (int j = 0; j <= bagWeight; j++){System.out.print(dp[j] + " ");}
}

动态规划背包问题优化空间复杂度——滚动数组相关推荐

  1. 【NOIP2015提高组】子串 区间DP+滚动数组优化

    题意: 有两个仅包含小写英文字母的字符串 A 和 B. 现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一个新的字符串. 请问 ...

  2. 动态规划-背包问题(1)

    - 刚开始听到背包问题时就感觉很熟悉,当老师举出基本的背包问题时就瞬间想起来贪心部分的背包问题,实在没有想明白到底区别在哪.于是我就去搜了一下动态规划这部分的背包问题是否能用贪心的方法解决,答案都是不 ...

  3. 01背包问题(当有的背包重量是非整数时)的递归(优化成动态规划+再用滚动数组优化)解法+一些动态规划(递归,搜索)的高级技巧

    当背包重量是整数时,动态规划可以用数组存储状态就可以了. 当背包重量是非整数时,用map存储状态就可以了!主要思路:  map(构造函数中参数comp是仿函数(或者叫函数对象))+递归优化(" ...

  4. 【LeetCode笔记】494. 目标和(Java、动态规划、背包问题、滚动数组)

    文章目录 题目描述 思路 && 代码 1. 动态规划 O(n2n^2n2).O(n2n^2n2)(最方便理解,初版) 2. 转换成 01 背包问题 O(n2n^2n2).O(nnn) ...

  5. 【LeetCode笔记】416. 分割等和子集(Java、动态规划、背包问题、滚动数组)

    文章目录 题目描述 思路 && 代码 1. 动态规划 O(nc) .O(nc) 2. 结合滚动数组 O(nc).O(c) 二刷 打卡第十四天-熬夜也得把题目补上= = 题目描述 初看题 ...

  6. 信息学奥赛一本通1267:【例9.11】01背包问题(二维dp与滚动数组优化)

    [题目描述] 一个旅行者有一个最多能装 MM 公斤的背包,现在有 nn 件物品,它们的重量分别是W1,W2,...,WnW1,W2,...,Wn,它们的价值分别为C1,C2,...,CnC1,C2,. ...

  7. 动态规划0-1背包问题滚动数组

    1.经典0-1背包问题 问题描述:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内选择物品使得物品的总价值最高. 回顾对于二维的0-1背包问题递推关系式: d p [ i ] [ j ] ...

  8. 【动态规划】01背包问题(滚动数组 + 手画图解)

    01背包除了可以用形象的二维动态数组表示外,还可以使用空间复杂度更低的一维滚动数组. 目录 文章目录 前言 一.滚动数组的基本理解 二.确定dp及其下标含义 三.确定递推公式 四.确定初始化 五.确定 ...

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

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

最新文章

  1. 第三百七十七节,Django+Xadmin打造上线标准的在线教育平台—apps目录建立,以及数据表生成...
  2. chrome动态ip python_用Python爬虫爬取动态网页,附带完整代码,有错误欢迎指出!...
  3. 第五十一期:互联网不如国企,去BAT的程序员都是diao丝?
  4. 史上最全的CSS hack方式一览(鉴)
  5. Uva_11235_Frequent values
  6. 在ubuntu中自定义安装nginx
  7. 创业公司研发团队面临的项目管理难题探讨
  8. 彻底搞懂遗传算法原理+代码讲解+具体例子
  9. 左程云 Java 笔记--图
  10. xpose 调试支付宝
  11. win7 matlab 7.0,win7环境下使用matlab7.0的方法
  12. python文件双击闪退_解决python文件双击运行秒退的问题
  13. zkLedger: Privacy-Preserving Auditing for Distributed Ledgers
  14. 小白通过JDBC在AndroidStudio一步步来访问MYSQL数据库
  15. Nginx-浅析(转)
  16. 传奇世界开服教程:传奇世界开服需要准备什么?前期需要投入多少?
  17. 干货|科技赋能财富硬核直播带货,助力宜信财富逆势增长
  18. GTD和掌握Omni系列效率工具
  19. 如何入职京东、华为、IBM等大厂?你需要学懂这门语言
  20. 什么是 CSDN ?

热门文章

  1. word从当前页面开始页码
  2. 间隔不到一年开两店,温州鸿雁全屋智能经销商透露了他的生意经
  3. 自己动手写一个java版QQ
  4. 学会这一招,即可实现视频一键去水印,太实用了
  5. 视频直播技术_直播如何实现低延迟
  6. 他把闲鱼APP长列表流畅度翻了倍(良心教程)
  7. vue将二维数组对象转为一维数组对象
  8. ensp 防火墙 USG6000V
  9. 九章算术更相减损术的的c语言实现
  10. 解决windows10下无法安装.net framework 3.5,错误代码0x800F081F