class Solution {
public:
int rob(vector<int>& nums) {
int n = nums.size();
// dp[i]:前 i 间房能偷到的最大收益
vector<int> dp(n + 1, 0);
dp[0] = 0;
dp[1] = nums[0];
for (int i = 2; i <= n; i++) {
// 不偷第 i 间:dp[i-1]
// 偷第 i 间:dp[i-2] + nums[i-1]
dp[i] = max(dp[i - 1], dp[i - 2] + nums[i - 1]);
}
return dp[n];
}
};
总结
1. dp 的含义
dp[i]
表示:
前 i 间房能够偷到的最大收益。
注意:dp[i] 是前 i 间 ,所以对应数组下标是 0 ~ i-1。
2. 递推公式
dp[i] = max(dp[i-1], dp[i-2] + nums[i-1]);
考虑第 i 间房:
-
不偷第 i 间 →
dp[i-1] -
偷第 i 间 → 前一间不能偷,所以只能用
dp[i-2],再加nums[i-1]
两种情况取最大值。
3. 为什么是 nums[i-1]
因为:
第 i 间房
↓
数组下标 i-1
所以代码中是:
nums[i-1]
4. 整体思路
可以直接记住这个模板:
dp[i]:前 i 个的最优结果
当前元素:
选它 → dp[i-2] + 当前值
不选它 → dp[i-1]
dp[i] = max(选,不选)
这就是这道题动态规划的核心。