你是乙個專業的小偷,計畫偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。給定乙個代表每個房屋存放金額的非負整數陣列,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額。
示例 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[i]
的含義,就是從左邊第乙個房子開始,到當前位置i
上能搶劫到的最高金額。明確了dp陣列的含義,下一步最重要也是最難的就是狀態轉移方程。當前位置上的最高金額怎麼得到?因為不能搶劫相鄰的房屋,所以可以有兩種方案:
比較兩種方案中哪個金額更大就作為當前位置上的最高金額。即:
dp[i] = max(dp[i-2]+nums[i], dp[i-1])
有兩個可能有疑問的地方:
為什麼不考慮i-2
之前的金額?因為之前的金額已經考慮在dp[i-2]
和dp[i-1]
之中了,所以考慮i-2
之前的金額就沒有意義了。
當前位置左邊乙個房子能偷到的最高金額dp[i-1]
,它可能不包含這個位置的房子,根據上面的轉移方程,dp[i-1] = max(dp[i-3]+nums[i-1], dp[i-2])
,所以dp[i-1]
可能是dp[i-2]
的值,不一定包含nums[i-1]
(即第i-1
間不一定被偷),那為什麼dp[i-1]
不能加上nums[i]
來得到dp[i]
呢?
對於第二個問題,我自己一開始的理解是這樣的:對於這種不確定是否包含num [i-1]
的情況,預設它是包含的,這樣就簡化了問題。參考了 krahets的題解發現我的理解是錯的。其實問題二這種情況是可以被忽略的。用假設法來解釋:
對空間的優化,由於只需要兩個變數來記錄i-2
和i-1
位置上的最高金額,故只需要兩個變數就可以了,不需要dp陣列。初始條件:兩個變數都為零,因為初始位置在第乙個房屋,左邊沒有房屋,所以兩個變數表示偷到的金額為零。
**如下:
class
solution
return pmax;
}}
題目:這個問題相比於原問題改動的地方是所有的房屋都圍成一圈,這意味著第乙個房屋和最後乙個房屋是緊挨著的。
思路:環狀排列意味著第乙個房子和最後乙個房子中只能選擇乙個偷竊,因此可以把此環狀排列房間問題轉化為兩個單排排列房間的子問題,最後取兩個子問題中較大的值就是整個環狀問題的最大值。(這種轉化的思想太重要了,之前的信封巢狀問題也是如此)
class
solution
public
introbcore
(int
nums)
return pmax;
}}
leetcode 打家劫舍問題
題目 你是乙個專業的小偷,計畫偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。給定乙個代表每個房屋存放金額的非負整數陣列,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額。分析 dp ...
LeetCode打家劫舍問題
打家劫舍i 簡單的dp 設定兩個陣列 f i 代表必偷第i個,g i 代表不偷第i個 class solution return max f n g n 打家劫舍ii 這裡跟第一題最大的區別在於第一家跟第n家不能同時偷 要麼偷1不偷n 要麼偷n不偷n 要麼都不偷 所以分類討論 第一種不選第一家 f ...
LeetCode 打家劫舍問題
q 你是乙個專業的小偷,計畫偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。給定乙個代表每個房屋存放金額的非負整數陣列,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額。示例 1 輸入...