动态规划原理 DP Principle
核心:状态定义和状态转移
自顶向下:记忆化搜索,即递归
自底向上:递推,即递推
01 198. House Robber
递归思路(自顶向下)
- 大白话:
- 自顶向下,从n开始,可以选择打劫或不打劫,自然其打劫的金额是不同的。选择打劫,则需要跳过n-1的房子的钱
- 公式
- dfs(i) = max(dfs(i-1), dfs(i-2)+nums[i])
- 记忆化搜索
- 由于dfs(n)需要知道dfs(n-1)和dfs(n-2),而dfs(n-1)需要知道dfs(n-2)和dfs(n-3)
- 可以发现他们都需要dfs(n-2),我们可以用一个cache数组把他们记忆住
- 时间复杂度:O(n)
- 空间复杂度:O(n)
- end
class Solution:
def rob(self, nums: List[int]) -> int:
n = len(nums)
if n <= 0:
return 0
if n <= 2:
return max(nums)
@cache
def dfs(i):
if i < 0:
return 0
if i == 0:
return nums[i]
return max(dfs(i-1), dfs(i-2)+nums[i])
return dfs(n-1)
递归(手动记忆化搜索)
class Solution:
def rob(self, nums: List[int]) -> int:
n = len(nums)
if n <= 0:
return 0
if n <= 2:
return max(nums)
cache = [-1] * n
def dfs(i):
if i < 0:
return 0
if i == 0:
return nums[i]
if cache[i] != -1:
return cache[i]
cache[i] = max(dfs(i-1), dfs(i-2)+nums[i])
return cache[i]
return dfs(n-1)