LC198-打家劫舍
198. 打家劫舍
法1:状态定义: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 + 1);
f[0] = nums[0];
f[1] = max(nums[0],nums[1]);
for(int i = 2; i < n; ++i)
f[i] = max(f[i-1],f[i-2] + nums[i]);
return f[n - 1];
}
};
法2:状态定义:f[i]
表示 以 i
结尾的并且选择了nums[i]
方案中获取的最高金额。
class Solution {
public:
int rob(vector<int>& nums) {
int n = nums.size();
vector<int>f(n + 1);
if(n == 1)return nums[0];
f[0] = nums[0];
f[1] = nums[1];
for(int i = 2; i < n; ++i)
for(int j = 0; j < i - 1; ++j)
f[i] = max(f[j] + nums[i], f[i]);
return max(f[n - 1],f[n - 2]);
}
};
优化:
class Solution {
public:
int rob(vector<int>& nums) {
int n = nums.size(), maxv = 0;
vector<int>f(n + 1);
if(n == 1)return nums[0];
f[0] = nums[0],f[1] = nums[1];
for(int i = 2; i < n; ++i){
maxv = max(maxv, f[i - 2]);
f[i] = max(maxv + nums[i], f[i]);
}
return max(f[n - 1],f[n - 2]);
}
};
法3: 状态定义:f[i][0]
表示没选nums[i]
,考虑前i个可以获得的最高金额,f[i][1]
表示选择了nums[i]
考虑前i个可以获得最高金额。
class Solution {
public:
int rob(vector<int>& nums) {
int n = nums.size();
vector<vector<int>>f(n + 1,vector<int>(2));
f[0][1] = nums[0];
for(int i = 1; i < n; ++i){
f[i][1] = f[i - 1][0] + nums[i];
f[i][0] = max(f[i - 1][0], f[i - 1][1]);
}
return max(f[n - 1][0],f[n - 1][1]);
}
};