Leetcode House Robber python 浅谈动态规划

Leetcode 198题 House Robber
You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.

Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.

Example 1:

Input: [1,2,3,1]
Output: 4
Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
             Total amount you can rob = 1 + 3 = 4.

Example 2:

Input: [2,7,9,3,1]
Output: 12
Explanation: Rob house 1 (money = 2), rob house 3 (money = 9) and rob house 5 (money = 1).
             Total amount you can rob = 2 + 9 + 1 = 12.

题目大意: 就是给你一排房子,你可以偷钱,但是房主为了防盗,把相邻的房子连接起来,不能同时被偷(无聊的防盗措施)。问你怎么偷能偷到最大值。
抽象问题,得出,给你一组数字集合,相邻的两个值只能取其一,问如何相加能加到最大值。

乍一看很难以理解,抽象出来,是一个“求最大值”问题。需要使用到动态规划方法。
怎么判断一个问题是否可以由动态规划来解决?
首先,如果一个问题有多种可能,看上去需要排列或者组合的思想,但是最终求的只是最优解,如最大值,最小值,最短子串,最长子串等,可以试试使用动态规划。

其实,状态转移方程是个关键。你可以用状态转移表来帮助自己理解整个过程。如果能找到准确的转移方程,那么离最终的代码实现也就不远了 。

这里说下什么是状态转移方程:从上一个状态到下一个状态之间可能存在一些变化,以及基于这些变化的最终决策结果。我们把这样的表达式称为状态转移方程。所有的动态规划算法中,状态转移是关键。

动态规划基本方程包含了三个条件,一状态转移方程,二最优值函数,三边界条件。状态转移方程就是动态过程的“动力”,我们在知道了k阶段的状态和决策后就可以得到k+1阶段的状态(反之同理),它把各个阶段联系起来了,因而我们才可以从边界条件通过递推得到最优解。


在本题中,我们遍历数字时,无非就判断,这家房子,“偷”还是“不偷”? “偷”的收益和“留着偷下一家”的收益那个大?
本题中,维护一个动态规划的集合,集合保存着偷这一家房子可带来的最大收益。以当前房子[i]为标准,是“留着”还是“偷”。
所以[i]的状态转移方程为:

dp[i] = max(dp[i-1], nums[i]+dp[i-2])
i的当前收益 = 取最大{留着不偷(还是i-1的收益),偷(当前房子加上i-2词的收益和)}

上代码:

class Solution:
    def rob(self, nums: List[int]) -> int:
        dp = [0] * len(nums)  #定义动态规划列表长度
        if not nums:
            return 0
        elif len(nums) == 1:
            return nums[0]
        dp[0] = nums[0]
        dp[1] = max(nums[0],nums[1])
        for i in range(2,len(nums)):
            dp[i] = max(dp[i-1], nums[i]+dp[i-2])
        return dp[-1]  #返回最后一个值。

又在某大神下看到如下代码。没有理解,但是通过。给出参考。

class Solution:
    def rob(self, nums: List[int]) -> int:
        now = last = 0
        for i in nums:
            last, now = now, max(i+last, now)  #这句没理解
        return now

以上。
2020/03/26
疫情下的英国。
加油!

发布了20 篇原创文章 · 获赞 1 · 访问量 794

猜你喜欢

转载自blog.csdn.net/weixin_43860294/article/details/105132467
今日推荐