動態規劃之 打家劫舍II

2021-10-08 21:06:50 字數 1861 閱讀 7276

你是乙個專業的小偷,計畫偷竊沿街的房屋,每間房內都藏有一定的現金。這個地方所有的房屋都圍成一圈,這意味著第乙個房屋和最後乙個房屋是緊挨著的。同時,相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。

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

示例 1:

輸入: [2,3,2]

輸出: 3

解釋: 你不能先偷竊 1 號房屋(金額 = 2),然後偷竊 3 號房屋(金額 = 2), 因為他們是相鄰的。

示例 2:

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

輸出: 4

解釋: 你可以先偷竊 1 號房屋(金額 = 1),然後偷竊 3 號房屋(金額 = 3)。

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

和打家劫舍i幾乎沒啥區別,最大的區別就在把所有的房子圍城乙個環了,所以就可以分成兩種情況來討論:①不偷第一家,偷最後一家nums[1:];②偷第一家,不偷最後一家nums[:-1];然後比較兩種情況下偷竊的最高金額,返回最大的金額即可。

class solution:

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

if not nums:

return 0

if len(nums)<=3:

return max(nums)

size = len(nums)

dp1 = [0]*(size-1)

dp2 = [0]*(size-1)

dp1[0]=nums[0]

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

dp2[0]=nums[1]

dp2[1]=max(nums[1],nums[2])

#nums[:n-1]

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

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

#nums[1:]

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

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

return max(dp1[-1],dp2[-1])

class solution(object):

def rob(self, nums):

n = len(nums)

if not nums:

return 0

if n == 1:

return nums[0]

if n == 3:

return max(nums)

#搶1~n-1家;搶2~n家;

#比較搶到哪家的最多

return max(self.rob1(nums[0:n - 1]), self.rob1(nums[1:n]))

def rob1(self, nums):

n = len(nums)

if not nums:

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 - 2] + nums[i], dp[i - 1])

return dp[-1]

總結:這個方法比較笨,應該給還有更聰明的方法。

動態規劃 打家劫舍II

題目 打家劫舍ii 在上次盜竊完一條街道之後,竊賊又轉到了乙個新的地方,這樣他就不會引起太多注意。這一次,這個地方的所有房屋都圍成一圈。這意味著第乙個房子是最後乙個是緊挨著的。同時,這些房屋的安全系統與上次那條街道的安全系統保持一致。給出乙份代表每個房屋存放錢數的非負整數列表,確定你可以在不觸動警報...

動態規劃 打家劫舍II

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

Leetcode 打家劫舍II(中等)動態規劃

題目描述 你是乙個專業的小偷,計畫偷竊沿街的房屋,每間房內都藏有一定的現金。這個地方所有的房屋都圍成一圈,這意味著第乙個房屋和最後乙個房屋是緊挨著的。同時,相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。給定乙個代表每個房屋存放金額的非負整數陣列,計算你在不...