力扣算法刷题Day42|动态规划:01背包问题 分割等和子集

力扣题目:01背包问题(二维数组)

刷题时长:参考题解

解题方法:动态规划 + 二维dp数组

复杂度分析

  • 时间
  • 空间

问题总结

  • 理解递推公式困难

本题收获

  • 动规思路:两层for循环,第一层i遍历物品,第二层j枚举背包容量以内所有值
    • 确定dp数组及下标的含义:dp[i][j] 表示从下标为[0-i]的物品范围 中任意取,放进容量为j的背包后价值总和的最大值
    • 确定递推公式:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i])
      • 当背包容量小于物品重量,不放物品,此时价值总和为dp[i - 1][j]。即当物品i的重量大于背包j的重量时,物品i无法放进背包中,所以背包内的价值依然和前面相同。
      • 当背包容量大于等于物品重量,放入物品i,此时价值总和最大值为dp[i - 1][j - weight[i]]。即为了放入物品i,先找到背包容量刚好完全放不下物品i时的价值总和最高值,再加上物品i的价值,此时即为背包容量足够时选择放入物品i后的总价值。
    • dp数组的初始化:
    • # 二维数组
          dp = [[0] * (bagweight + 1) for _ in range(len(weight))]
      
          # 初始化
          for j in range(weight[0], bagweight + 1):
              dp[0][j] = value[0]
      
    • 确定遍历顺序:二维数组中,先遍历背包容量还是物品都可行

力扣题目:01背包问题(滚动数组)

刷题时长:参考题解

解题方法:动态规划 + 一维dp数组

复杂度分析

  • 时间
  • 空间

问题总结

  • for循环遍历顺序为什么不能交换

本题收获

  • 动规思路
    • 确定dp数组及下标的含义:在一维dp数组中,dp[j]表示:容量为j的背包,所背的物品价值可以最大为dp[j]
    • 确定递推公式:dp[j] = max(dp[j], dp[j - weight[i]] + value[i])
      • 此时dp[j]有两个选择,一个是取自己dp[j],相当于二维dp数组中的dp[i-1][j],即不放物品i;一个是取dp[j - weight[i]] + value[i],即放物品i。两者取大的得到价值最大值
    • dp数组的初始化:都为0
    • 确定遍历顺序:正序遍历物品,倒序遍历背包
  • 相比二维数组,用一维数组实现的区别:
    • 双循环的次序不能颠倒,必须先物品,再背包:dp[j]代表了二维数组中上一层放入物品i-1后的最大价值,和当前我们放入物品i后的总价值进行对比,比较之后再覆盖并更新为当前最大值
    • 背包的遍历顺序必须为倒序:以保证物品i只被放入了一次

力扣题目:#416. 分割等和子集

刷题时长:参考题解后10min

解题方法:动态规划

复杂度分析

  • 时间O(n^2)
  • 空间O(n)

问题总结

  • 如何能抽象为01背包问题

本题收获

  • 转换为01背包问题:本题中每一个元素的数值既是重量,也是价值
    • 背包的体积为sum / 2
    • 背包要放入的商品(集合里的元素)重量为 元素的数值,价值也为元素的数值
    • 背包如果正好装满,说明找到了总和为 sum / 2 的子集。
    • 背包中每一个元素是不可重复放入
  • 动规思路
    • 确定dp数组及下标的含义:容量为j的背包,所背的物品价值最大可以为dp[j]
    • 确定递推公式:dp[j] = max(dp[j], dp[j - nums[i]] + nums[i])
    • dp数组的初始化:都为0
    • 确定遍历顺序:第一层正序,第二层倒序
  • 在第二层循环中左边界设为i-1,即背包容量枚举到大小等于i时就跳出,因为此时背包是装不下物品i的,无需再进一步写条件判断背包容量是否足够
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值