Leetcode初级算法 打家劫舍(动态规划)(Python实现)

问题描述:

算法思想:

该问题的内在逻辑结构依然是动态规划里的经典结构。最关键的是推出状态转移方程,当前规模的对应解法由更低规模的解法,仿佛拾级而上,站在前人的肩膀上不断攀登。

实际操作起来,比较实用的方法如下:固定一个比较小的规模n, 进行思维实验。

例子:

nums = [2,7,9,3,1],求这个数组对应的最高金额。

 我们要做的是拿着某个规模的解,去求更高规模的解。用数组memo记录每个规模对应的解(最高金额),memo[i]对应的是nums的子数组nums[:i](子问题)对应的解(最高金额)。这个过程就是从左向右顺序扫描nums数组,一边扫描一边将求出的解存储为memo[i]。假定现在扫描到i = 3,此时子数组为nums[:3] = [2,7,9],我们来手算一下memo,得到memo[:3] = [2, 7, 11]。

好了,现在扫描到nums下一项,i = 4,nums[:4] = [2,7,9,3],现在我们来求memo的第四项,也就是下一规模的解。对应这第四个屋子(nums[3] = 3),作为一个贼我们有两个选择:偷或是不偷。如果我没有偷第三家屋子,那就不用担心偷第四家会触发报警,那就放心偷好了;如果我偷了第三家,那就要斟酌一下偷不偷第四家了。偷第四家就必定要放弃第三家,但如果第四家钱特别多,那还是不亏的。i = 3时我们的选择是偷2 和 9,收益是11;i = 4时,如果偷3就只能 7+3,收益是10,不划算,果断不偷。memo更新为[2,7,11,11]。

类似地,继续扫描,i = 5,nums[:5] = [2,7,9,3,1],还是那个问题——这家屋子偷还是不偷。因为我们放弃了第四家,不存在相邻问题,放心偷就好。

发现规律了吗?下一规模的解,也就是memo[n],要么是memo[n-1] (不偷,保持原状),或是memo[n-2]+nums[n](放弃上一家,偷这家)。由于程序不知道上一家有没有偷,我们两个选择都算一下,取较大值即可。

 

代码:

class Solution(object):
    def rob(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if nums == []:  return 0
        n = len(nums)
        if n == 1:  return nums[0]
        memo = [nums[0] for i in range(n)]
        memo[1] = max(nums[:2])
        for i in range(2,n):
            choice1 = memo[i-1]
            choice2 = memo[i-2]+nums[i]
            memo[i] = max(choice1,choice2)
        return memo[n-1]
        
        
        

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值