代码随想录算法训练营第四十三天| 474.一和零,494. 目标和,1049. 最后一块石头的重量 II

代码随想录算法训练营第四十三天

  • 474.一和零
  • 494. 目标和
  • 1049. 最后一块石头的重量 II

474.一和零

代码

#  !/usr/bin/env  python
#  -*- coding:utf-8 -*-
# @Time   :  2022.12
# @Author :  hello algorithm!
# @Note   :  https://leetcode.cn/problems/ones-and-zeroes/
from typing import List


class Solution:
    """
    dp[i][j] 表示最多有i个0和j个1的最大子集大小为dp[i][j]
    dp[i][j] = max(dp[i-num_zeros][j-num_ones]+1,dp[i][j])
    """

    def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
        dp = [[0 for _ in range(n + 1)] for _ in range(m + 1)]
        for str in strs:
            num_zeros, num_ones = 0, 0
            for s in str:
                if s == '0':
                    num_zeros += 1
                else:
                    num_ones += 1
            for i in range(m, num_zeros - 1, -1):
                for j in range(n, num_ones - 1, -1):
                    dp[i][j] = max(dp[i - num_zeros][j - num_ones] + 1, dp[i][j])
        return dp[m][n]


if __name__ == '__main__':
    strs = ["1"]
    m = 5
    n = 3
    s = Solution()
    print(s.findMaxForm(strs, m, n))

494. 目标和

代码

#  !/usr/bin/env  python
#  -*- coding:utf-8 -*-
# @Time   :  2022.12
# @Author :  hello algorithm!
# @Note   :  https://leetcode.cn/problems/target-sum/
from typing import List


class Solution:
    """
    求目标和为target,已知数组nums,总和nums_sum = sum(nums),根据运算符号,分成两组A和B
    假设A>B,则A-B = target,A+B=nums_sum
    则A = (nums_sum + target) // 2
    递推公式:
    dp[j] 表示装满容量为j的背包共dp[j]种方法
    dp[j] += dp[j-nums[i]]
    """

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


if __name__ == '__main__':
    nums = [1, 1, 1, 1, 1]
    target = 3
    s = Solution()
    print(s.findTargetSumWays(nums, target))

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

代码

#  !/usr/bin/env  python
#  -*- coding:utf-8 -*-
# @Time   :  2022.12
# @Author :  hello algorithm!
# @Note   :  https://leetcode.cn/problems/last-stone-weight-ii/
from typing import List


class Solution:
    """
    将stones分成两组重量接近的数组,总重量为sum(stones),求sum(stones)//2的背包,最大能装的重量为A
    则最终的结果为sum(stones)-2*A
    一维数组递推公式:
    dp[j] = max(dp[j],dp[j-stones[i]] + stones[i])
    """

    def lastStoneWeightII(self, stones: List[int]) -> int:
        target = sum(stones) // 2
        # dp数组初始化为0
        dp = [0] * (target + 1)
        # dp数组遍历
        for i in range(len(stones)):
            for j in range(target, stones[i] - 1, -1):
                dp[j] = max(dp[j], dp[j - stones[i]] + stones[i])
        return sum(stones) - dp[target] * 2


if __name__ == '__main__':
    stones = [31, 26, 33, 21, 40]
    s = Solution()
    print(s.lastStoneWeightII(stones))

你可能感兴趣的:(算法,动态规划,leetcode)