第42天|dp

文章讨论了如何运用动态规划方法解决0-1背包问题的变种——PartitionEqualSubsetSum问题。通过设置二维dp数组,根据物品重量和价值更新状态,找到数组中是否存在一种分割方式使得两部分的和相等。两种方法分别展示了不同的dp初始化和状态转移策略,最终检查dp数组的特定位置来确定解的存在性。
摘要由CSDN通过智能技术生成

今天的主要的目的是理解0-1背包问题.dp[i][j]代表到物品i位置,容量j能最多装多少价值的东西.那么递推公式就是dp[i][j]=max(dp[i-1][j], dp[i-1][j-weight[i]+value[i]) 前者表示不放物品i的情况,后者表示放物品i的情况

416. Partition Equal Subset Sum

这道题是0-1背包的一道变种题,基本思路就是算dp[-1][-1]==sum(nums).

Way1:

地推公式的变化在于如果nums[i]比当前的j值大,是肯定不能放入的,反之则是常规的递推公式.

初始化上首先全都置0. 其次对于dp[i][0]来说应该也是0因为所有的num都会大于0. 对于dp[0][j]来说,就需要进行比较.比较的方法就是如果当前的j大于nums[0]那么就置成nums[0]

除此之外还需要开始和最后的比较.开始的比较是要判断sum是不是个偶数,还有一个就是最后的值是否能等于sum//2

class Solution:
    def canPartition(self, nums: List[int]) -> bool:
        target=sum(nums)
        nums.sort()
        if target%2==1:
            return False
        target=target//2
        dp=[[0 for _ in range(target+1)] for _ in range(len(nums))]
        for i in range(len(nums)):
            dp[i][0]=0
        for j in range(1,target):
            if nums[0]<=j:
                dp[0][j]=nums[0]
        for i in range(1,len(nums)):
            for j in range(1,target+1):
                if nums[i]<=j:
                    dp[i][j]=max(dp[i-1][j],dp[i-1][j-nums[i]]+nums[i])
                else:
                    dp[i][j]=dp[i-1][j]
        return dp[-1][target]==target

Way2:

这种方法更加的巧妙.直接把dp置成true & false,基本思路不变

class Solution(object):
    def canPartition(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        s=sum(nums)//2
        if sum(nums)%2==1:
            return False
        l=len(nums)
        dp = [[False for _ in range(s+1)] for _ in range(l+1)]
        
        for i in range(l+1):
            dp[i][0]=True
            
        for i in range(1,l+1):
            for t in range(1,s+1):
                if nums[i-1] <= t:
                    dp[i][t]=dp[i-1][t] or dp[i-1][t-nums[i-1]]
                else:
                    dp[i][t]=dp[i-1][t]
        return dp[l-1][s]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值