Leetcode198.打家劫舍

198. 打家劫舍

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警

给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

示例 1:

1
2
3
4
>输入:[1,2,3,1]
>输出:4
>解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
偷窃到的最高金额 = 1 + 3 = 4 。

示例 2:

1
2
3
4
>输入:[2,7,9,3,1]
>输出:12
>解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
偷窃到的最高金额 = 2 + 9 + 1 = 12 。

定义子问题:

原问题是 “从全部房子中能偷到的最大金额”,将问题的规模缩小,子问题就是 “从 k 个房子中能偷到的最大金额 ”,用 f(k) 表示。

image-20240902134318833

假设有n个房子,那么偷到第k个房子(不偷第K个)时候最大的金额就变成讨论两种情况:

1.不偷第k-1个房子,那么偷到第k个房子的钱就和偷前k-2个房子是一样的

2.偷k-1个房子,那么就不能偷第k-2号房子

image-20240902134341239

此时我们能够获得递推公式:

$$f(k)=max{f(k−1),H**k−1+f(k−2)}$$

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution(object):
def rob(self, nums):
if len(nums) == 0:
return 0
# 构建dp备忘录数组
N = len(nums)
dp = [0] * (N+1)

dp[0] = 0
dp[1] = nums[0]
for k in range(2, N+1):
dp[k] = max(dp[k-1], nums[k-1] + dp[k-2])
return dp[N]