Day 37 | 01背包问题 、416. 分割等和子集

01背包问题 二维dp

https://programmercarl.com/背包理论基础01背包-1.html
视频讲解:https://www.bilibili.com/video/BV1cg411g7Y6
有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。

思考

dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少。

def test_2_wei_bag_problem1():
    weight = [1, 3, 4]
    value = [15, 20, 30]
    bagweight = 4

    # 二维数组
    dp = [[0] * (bagweight + 1) for _ in range(len(weight))]

    # 初始化
    for j in range(weight[0], bagweight + 1):
        dp[0][j] = value[0]

    # weight数组的大小就是物品个数
    for i in range(1, len(weight)):  # 遍历物品
        for j in range(bagweight + 1):  # 遍历背包容量
            if j < weight[i]:
                dp[i][j] = dp[i - 1][j]
            else:
                dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i])

    print(dp[len(weight) - 1][bagweight])

test_2_wei_bag_problem1()

01背包问题 一维dp

https://programmercarl.com/背包理论基础01背包-2.html
视频讲解:https://www.bilibili.com/video/BV1BU4y177kY

思考

在一维dp数组中,dp[j]表示:容量为j的背包,所背的物品价值可以最大为dp[j]。

思考

使用滚动数组,先物品再背包。背包遍历需要逆序,正序的话上一层的左侧值就被覆盖了,无法滚动。

def test_1_wei_bag_problem():
    weight = [1, 3, 4]
    value = [15, 20, 30]
    bagWeight = 4

    # 初始化
    dp = [0] * (bagWeight + 1)
    for i in range(len(weight)):  # 遍历物品
        for j in range(bagWeight, weight[i] - 1, -1):  # 遍历背包容量
            dp[j] = max(dp[j], dp[j - weight[i]] + value[i])

    print(dp[bagWeight])

416. 分割等和子集

本题是 01背包的应用类题目
https://programmercarl.com/0416.分割等和子集.html
视频讲解:https://www.bilibili.com/video/BV1rt4y1N7jE

思考

暴力回溯太费事了。
转换为01背包问题。背包容量为sum/2,物品重量为nums[i],价值也是nums[i]
dp[i] 背包容量i是否可以装满

class Solution:
    def canPartition(self, nums: List[int]) -> bool:
        if len(nums)==1:
            return False
        sum_ = sum(nums)
        if sum_ % 2 !=0:
            return False
        k = int(sum_ / 2)
        # dp[i] 背包容量i是否可以装满
        dp = [False] * (k+1)
        dp[0] = True
        for num in nums:
            for i in range(k,0,-1):
                if i>=num:
                    dp[i] = dp[i] or dp[i-num]
        return dp[k]
posted @   forrestr  阅读(12)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示