Leetcode刷题(11) 背包问题系列(动态规划)

    技术2025-12-06  9

    Leetcode刷题(11) 背包问题系列(动态规划)

    416. 分割等和子集

    参考labuladong的经典动态规划:0-1 背包问题,经典动态规划:0-1背包问题的变体

    # 0-1背包问题的变体 class Solution(object): def canPartition(self, nums): """ :type nums: List[int] :rtype: bool """ size = len(nums) Sum = 0 # 计算总数和 for num in nums: Sum += num # 如果是奇数的话则nums无法被分割成两个等和的子集 if Sum % 2 != 0: return False # 取得一半作为背包的容量 Sum = Sum / 2 dp = [[False] * (Sum + 1) for _ in range(size + 1)] # 如果背包的容量为0的时候, 肯定可以装满 for i in range(size + 1): dp[i][0] = True for i in range(1, size + 1): for w in range(1, Sum + 1): # 当前背包的容量不够, 第i个物品无法装入 if w - nums[i-1] < 0: dp[i][w] = dp[i-1][w] else: # 选择不装还是装, 只要一个符合就行 dp[i][w] = dp[i-1][w] or dp[i-1][w-nums[i-1]] return dp[size][Sum]

    518. 零钱兑换 II

    具体方法参考labuladong的经典动态规划:完全背包问题

    class Solution(object): def change(self, amount, coins): """ :type amount: int :type coins: List[int] :rtype: int """ num_coins = len(coins) # base case dp = [[0] * (amount + 1) for _ in range(num_coins + 1)] for i in range(num_coins + 1): dp[i][0] = 1 for i in range(1, num_coins + 1): for j in range(1, amount + 1): if j - coins[i-1] < 0: # 放不下, 那第i种硬币就不能用 dp[i][j] = dp[i-1][j] else: # 不用第i种硬币 + 用第i种硬币,注意这里是dp[i][j-coins[i-1]]不是dp[i-1][j-coins[i-1]],因为是完全背包问题,每种硬币的个数无限 dp[i][j] = dp[i-1][j] + dp[i][j-coins[i-1]] return dp[num_coins][amount]

     

    Processed: 0.014, SQL: 10