状态的定义是f[i]表示前i个房间能偷到的最大利润, 进一步可以优化滚动数组。
class Solution {
public:
int rob(vector<int>& nums) {
int n = nums.size();
if(n == 0) return 0;
if(n == 1) return nums[0];
vector<int> f(n);
// f[i] 表示前i个房间能偷到的最大金额
f[0] = nums[0];
f[1] = max(nums[1], nums[0]);
for(int i = 2; i < n; i++){
f[i] = max(f[i - 1], f[i - 2] + nums[i]);
}
return f[n - 1];
}
};
按是否偷第一个房间进行分类,递推两次即可。
class Solution {
public:
int rob(vector<int>& nums) {
int n = nums.size();
if(n == 0) return 0;
if(n == 1) return nums[0];
vector<int> f(n);
f[0] = nums[0];
f[1] = nums[0];
for(int i = 2; i < n - 1; i++){
f[i] = max(f[i - 1], f[i - 2] + nums[i]);
}
int res = f[n - 2];
f[0] = 0;
f[1] = nums[1];
for(int i = 2; i < n; i++){
f[i] = max(f[i - 1], f[i - 2] + nums[i]);
}
res = max(res, f[n - 1]);
return res;
}
};