# 代码随想录算法训练营第38天 | 01背包问题:1049.最后一块石头的重量II(最多能装多少)、494.目标和(组合问题)、474. 一和零(二维01组合)

1049.最后一块石头的重量II
https://leetcode.cn/problems/last-stone-weight-ii/
代码随想录
https://programmercarl.com/1049.最后一块石头的重量II.html#算法公开课
494.目标和
https://leetcode.cn/problems/target-sum/description/
代码随想录
https://programmercarl.com/0494.目标和.html#算法公开课
474.一和零
https://leetcode.cn/problems/ones-and-zeroes/description/
代码随想录
https://programmercarl.com/0474.一和零.html#思路

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

题解思路

  • dp算法含义
    • dp[i][j] 第i个石头在j的重量限制下 最大重量;
    • 循环顺序 倒序 j在当前循环的st之前停止;

题解代码

class Solution:
    def lastStoneWeightII(self, stones: List[int]) -> int:
        target = sum(stones)//2
        dp = [0]*(target+1)

        for st in stones:
            for j in range(target,st-1,-1):
                dp[j] = max(dp[j],dp[j-st]+st)
        return sum(stones)-dp[-1]-dp[-1]

494. 目标和

题解思路

  • dp[j]:第j容积大的包,有dp[j]种方法;
  • 递推公式:dp[j]+=dp[j-nums[i]]

题解代码

class Solution:
    def findTargetSumWays(self, nums: List[int], target: int) -> int:
        if (sum(nums)+target)%2!=0 or abs(sum(nums))<abs(target):
            return 0 
        x = (sum(nums)+target)//2
        dp = [0]*(x+1)
        dp[0] = 1

        for num in nums:
            for j in range(x,num-1,-1):
                dp[j] += dp[j-num]
        return dp[-1]

474.一和零

题解思路

  • dp[i][j] s在i个0 j个1限制下 最大的个数;
  • 遍历顺序:正常01背包 变成二维数组理解;

题解代码

class Solution:
    def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
        dp = [[0]*(n+1) for _ in range(m+1)]

        for s in strs:
            zero_num = s.count("0")
            one_num = len(s)-zero_num
            for i in range(m,zero_num-1,-1):
                for j in range(n,one_num-1,-1):
                    dp[i][j] = max(dp[i][j],dp[i-zero_num][j-one_num]+1)
        return dp[-1][-1]
posted @ 2024-07-23 15:28  哆啦**  阅读(1)  评论(0编辑  收藏  举报