天天看點

[動态規劃]Leetcode 198.打家劫舍(python)[動态規劃]Leetcode 198.打家劫舍(python)

[動态規劃]Leetcode 198.打家劫舍(python)

題目描述

你是一個專業的小偷,計劃偷竊沿街的房屋。每間房内都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有互相連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。

給定一個代表每個房屋存放金額的非負整數數組,計算你 不觸動警報裝置的情況下 ,一夜之内能夠偷竊到的最高金額。

示例1

輸入:[1,2,3,1]

輸出:4

解釋:偷竊 1 号房屋 (金額 = 1) ,然後偷竊 3 号房屋 (金額 = 3)。

偷竊到的最高金額 = 1 + 3 = 4 。

示例2

輸入:[2,7,9,3,1]

輸出:12

解釋:偷竊 1 号房屋 (金額 = 2), 偷竊 3 号房屋 (金額 = 9),接着偷竊 5 号房屋 (金額 = 1)。

偷竊到的最高金額 = 2 + 9 + 1 = 12 。

DP定義及狀态方程

定義

dp[i]

表示前 i間房屋能偷竊到的最高總金額。

那麼對于第

i

個房間有偷與不偷兩種選擇,

  1. 如果不偷第

    i

    個房間,那麼

    dp[i]

    dp[i-1]

    相等;
  2. 如果偷第

    i

    個房間,那麼

    dp[i]

    dp[i-2]

    的值再加上

    nums[i]

    ,因為偷了第

    i

    個房間,那麼第

    i-1

    個房間一定不能偷,此時

    dp[i]=dp[i-2]+nums[i]

    是以對于第

    i

    個房間能夠偷到的最大值為

    dp[i] = max(dp[i-1],dp[i-2]+nums[i])

此題目的最終答案即為

dp

數組中的最大值:

dp[n-1]

,

n

表示房間個數。

初始邊界條件

dp[0]=nums[0]

:隻有一個房間,隻能偷一個,

dp[1] = max(nums[0],nums[1])

:兩個房間的話取最大的一個偷。

最終代碼

class Solution:
    def rob(self, nums: List[int]) -> int:
        #dp[i] 表示前 i間房屋能偷竊到的最高總金額
        #dp[i] = max(dp[i-1],dp[i-2]+nums[i])  
        n = len(nums)
        if n==0:
            return 0
        if n==1:
            return nums[0]
        dp = [0]* n
        dp[0] = nums[0]
        dp[1] = max(nums[0],nums[1])
        for i in range(2,n):
            dp[i] = max(dp[i-1],dp[i-2]+nums[i])
        return dp[n-1]
           

想更詳細的了解動态規劃思路解法,可以點選連結查閱我之前的一篇博文《算法之【動态規劃】詳解》,很詳細的介紹了動态規劃求解思路及方法。

如果喜歡作者,歡迎點贊、收藏及關注,謝謝!

歡迎掃描下面二維碼關注公衆号:阿旭算法與機器學習, 和作者共同學習交流。

[動态規劃]Leetcode 198.打家劫舍(python)[動态規劃]Leetcode 198.打家劫舍(python)