day36-dynamic programming-part04-8.7

tasks for today:

1. 1049.最后一块石头的重量II

2. 494.目标和

3. 474.一和零

--------------------------------------------------------------------------

1. 1049.最后一块石头的重量II

本题其实就是尽量让石头分成重量相同的两堆,相撞之后剩下的石头最小,这样就化解成01背包问题了

This is similar to the practice 416, the only difference is the return value

def lastStoneWeightII(self, stones: List[int]) -> int:
        if len(stones) == 1:
            return stones[0]
        target = sum(stones) // 2
        dp = [0] * (target + 1)
        for i in range(0, len(stones)):
            # method 1
            for j in range(target, 0, -1):
                if j >= stones[i]:
                    dp[j] = max(dp[j], dp[j-stones[i]] + stones[i])
            # method 2
            # for j in range(target, stones[i] - 1, -1):
            #     dp[j] = max(dp[j], dp[j - stones[i]] + stones[i])
        
        return (sum(stones) - dp[-1]) - dp[-1]

2. 494.目标和

In this practice, the first thought leading it to a 01 backpack problem would be the separtion of two group, this also stress the importance of the practice 416, which serve as the basic idea for a lot of practices.

SO the essence of this practice is to find the proper bagsize first, which is derived by following two equations: left + right = sum; left - right = target -> then the left = (sum+target)/2 would be the bagsize.

1st pitfall: special condition for return 0

2nd pitfall: the target for judging target and sum should be processed by abs()

3rd pitfall: the initialization of dp, the fist entry should be 1, while the left are all 0, this is subject to the recursive equation, which is not max() anymore, instead, it is cululating.

class Solution:
    def findTargetSumWays(self, nums: List[int], target: int) -> int:
        if (sum(nums) + target) % 2 == 1: return 0
        if abs(target) > sum(nums): return 0
        bagsize = (sum(nums) + target) // 2
        dp = [0] * (bagsize + 1)
        dp[0] = 1
        for i in range(len(nums)):
            # method 1
            for j in range(bagsize, 0, -1):
                if j >= nums[i]:
                    dp[j] += dp[j-nums[i]]
            # method 2
            for j in range(bagsize, nums[i]-1, -1):
                dp[j] += dp[j-nums[i]]
        
        return dp[-1]

3. 474.一和零

In this practice, there are two constraint dimentions for the backpack, which is the amount of "0" and "1", so the correspodning weight list and value list should also be two dimentions. in this practice, the dp store the max number, so there is no value list.

pay attention to the initial construction of dp list, i.e., the sequence of m and n

class Solution:
    def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
        dp = [[0] * (n+1) for _ in range(m+1)]
        for i in range(len(strs)):
            zero_num = strs[i].count('0')
            one_num = len(strs[i]) - zero_num
            for j in range(m, zero_num-1, -1):
                for k in range(n, one_num-1, -1):
                    dp[j][k] = max(dp[j][k], dp[j-zero_num][k-one_num] + 1)
        
        return dp[-1][-1]
  • 12
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值