198 打家劫舍(動態規劃)

2021-10-20 02:13:44 字數 1420 閱讀 9654

1. 問題描述:

你是乙個專業的小偷,計畫偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。給定乙個代表每個房屋存放金額的非負整數陣列,計算你不觸動警報裝置的情況下 ,一夜之內能夠偷竊到的最高金額。

示例 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 。

2. 思路分析:

① 分析題目可以知道最簡單的辦法就是嘗試所有可能的組合方案,但是由於遞迴的話資料規模很大,所以可以考慮使用動態規劃(優化的暴力破解)的思路解決,動態規劃中最核心的是狀態轉移和狀態計算,我們可以從比較簡單的幾個資料進行模擬,如果只有一間屋子那麼偷的最大金額就為當前屋子的金額,如果為兩間屋子那麼為兩件屋子的金額的較大值,如果為三間屋子那麼可以嘗試偷第三間屋子,由於偷相鄰兩間屋子會報警所以只能夠再偷第一間屋子,第二種方案是不偷第三間屋子那麼就只能夠偷第二間屋子,由此可以得到有三間屋子的時候為第一間屋子與第三間屋子的和與第二間屋子的較大值,所以對於第n間屋子我們可以分析得到偷第n間屋子 + n - 2間屋子偷的金額的最大值,或者是不偷第n間屋子也即為前面n - 1間屋子偷的最大金額,分析可以得到遞推公式為:dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]),使用一維的dp陣列或者列表就可以解決,dp[i]表示有i間屋子偷的最大金額

3. **如下:

from typing import list

class solution:

def rob(self, nums: list[int]) -> int:

if len(nums) == 0: return 0

# 小於等於2的時候取出其中的最大值即可

if len(nums) <= 2: return max(nums)

dp = [0] * len(nums)

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

for i in range(2, len(nums)):

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

return dp[len(nums) - 1]

198 打家劫舍(動態規劃)

你是乙個專業的小偷,計畫偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。給定乙個代表每個房屋存放金額的非負整數陣列,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額。示例 1 輸入 1...

198 打家劫舍

很明顯是dp問題。用乙個一維陣列表示dp陣列,狀態轉移方程為 resmax index max nums index resmax index 2 resmax index 1 其中resmax儲存,遍歷到該節點時的,最大值。注意,遍歷到該節點,但該節點不一定選。另外該題的初始解要想清楚。即resm...

198 打家劫舍

你是乙個專業的小偷,計畫偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。給定乙個代表每個房屋存放金額的非負整數陣列,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額。示例 1 輸入 1...