代码随想录算法训练营第四十六天| 多重背包理论、LeetCode198.打家劫舍、LeetCode213.打家劫舍II、LeetCode337.打家劫舍 III

多重背包

多重背包可以理解为每个物品有多个,但是有使用限制,这就介于01背包和完全背包之间

198.打家劫舍

题目描述: 198.打家劫舍.

解法

dp

class Solution(object):
    def rob(self, nums):
        dp = [0] * (len(nums)+1)
        dp[1] = nums[0]
        for i in range(2,len(nums)+1):
            dp[i] = max(dp[i-1],dp[i-2]+nums[i-1])
        return dp[len(nums)]

跳出背包!已经不是背包问题了!

213.打家劫舍II

题目描述: 213.打家劫舍II.

解法

dp

class Solution(object):
    def robrange(self,nums):
        dp = [0] * (len(nums)+1)
        dp[1] = nums[0]
        for i in range(2,len(nums)+1):
            dp[i] = max(dp[i-1],dp[i-2]+nums[i-1])
        return dp[len(nums)]
    def rob(self, nums):
        if len(nums) == 1:
            return nums[0]
        money1 = self.robrange(nums[1:])
        money2 = self.robrange(nums[:-1])
        return max(money1,money2)

遇到环,就考虑首尾元素。因为他们是挨着的,只能选一个或者都不选。

337.打家劫舍 III

题目描述: 337.打家劫舍 III.

解法

dp

class Solution(object):
    def robTree(self,root):
        if not root:
            return [0,0]
        left = self.robTree(root.left)
        right = self.robTree(root.right)

        rob_val = root.val + left[1] + right[1]
        not_rob_val = max(left) + max(right)
        return [rob_val,not_rob_val]
    def rob(self, root):
        return max(self.robTree(root))

遇到树的动态规划,可以仅使用n个元素的数组,表示n个状态,由于树的遍历是递归的,因此每一个节点都会产生一个这样的状态数组最后取max即可。

你可能感兴趣的:(算法)