Day 42 代码随想录 背包问题

文章介绍了0-1背包问题的二维和一维动态规划解法,以及如何将分割等和子集问题抽象为0-1背包问题来解决。在0-1背包问题中,通过动态规划求解放入物品的最大价值,而在416.分割等和子集问题中,寻找数组能否分割成两个和相等的子集。
摘要由CSDN通过智能技术生成


0-1 背包问题

   题目链接:0-1 背包问题
在这里插入图片描述

 
思路

  1. dp[i][j]的含义,即放入i个物品最大重量为j的最大价值。
  2. 初始化,注意第一行的值。
  3. 如果当前的重量大于最大重量,即前一个放入物品的最大价值为当前值
  4. 反之就是比较,-1就是与少一件的进行比较。

二维解法

weight=[1,3,4]
values=[15,20,30]
bag_size=4
dp=[[0]*(bag_size+1) for _ in range(len(weight))]
for i in range(1,bag_size+1):
    if weight[0]<=i:
        dp[0][i]=values[0]
for i in range(1,len(weight)):#遍历物品
    cur_weight,cur_value=weight[i],values[i]
    for j in range(1,bag_size+1):#重量
        if cur_weight>j:
            dp[i][j]=dp[i-1][j]
        else:
        #dp[i-1][j]表示不放入物品
            dp[i][j]=max(dp[i-1][j],dp[i-1][j-cur_weight]+cur_value)

一维解法

weight = [1, 3, 4]
value = [15, 20, 30]
bag_weight = 4
# 初始化: 全为0
dp = [0] * (bag_weight + 1)

# 先遍历物品, 再遍历背包容量
for i in range(len(weight)):
    for j in range(bag_weight, weight[i] - 1, -1):
        # 递归公式
        dp[j] = max(dp[j], dp[j - weight[i]] + value[i])
	for j in range(bag_weight, weight[i] - 1, -1)  ,表示已经放入了多少重量的物品。

需要仔细理解。

416. 分割等和子集

   题目链接:416. 分割等和子集
在这里插入图片描述

 
  这题抽象成0-1背包问题,就是有没有使得背包价值为sum/2的。

class Solution(object):
    def canPartition(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        Sum=sum(nums)
        if Sum%2==1:
            return False
        target=Sum/2
        dp=[0]*(target+1)
        for i in range(len(nums)):
            for j in range(target,nums[i]-1,-1):
                dp[j]=max(dp[j],dp[j - nums[i]] + nums[i])
                if dp[j]==target:
                    return True
        return False
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值