1 题目
You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.
Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.
Example 1:
Input: [1,2,3,1]
Output: 4
Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
Total amount you can rob = 1 + 3 = 4.
Example 2:
Input: [2,7,9,3,1]
Output: 12
Explanation: Rob house 1 (money = 2), rob house 3 (money = 9) and rob house 5 (money = 1).
Total amount you can rob = 2 + 9 + 1 = 12.
2 尝试解
2.1 分析
给定一个数组nums,在不能取相邻元素的情况下,问可以取到的最大和是多少。
dp[i]表示在前i+1个数中,取nums[i]的最大和,则dp[i-1]不可取,dp[i] = nums[i] + max(dp[i-2]+dp[i-3])。如果i-2,i-3都没有取,则i-1,i-2,i-3都没有取,那么就不是最大和,假设不成立。
也可以换一种思路,类似于背包问题,dp[i]表示在前i+1个数中,不能取相邻元素的情况下,可以取到的最大和。则dp[i] = max(nums[i]+dp[i-2],dp[i-1])。又dp[i]只与前两项有关,可以只用两个变量记录即可。
2.2 代码
class Solution {
public:
int rob(vector<int>& nums) {
if(nums.size()==0) return 0;
if(nums.size()==1) return nums[0];
if(nums.size()==2) return max(nums[0],nums[1]);
if(nums.size()==3) return max(nums[1],nums[0]+nums[2]);
vector<int> saver(nums.size());
saver[0] = nums[0];
saver[1] = nums[1];
saver[2] = nums[2]+nums[0];
for(int i = 3; i < nums.size();i++){
saver[i] = max(saver[i-2],saver[i-3])+nums[i];
}
return max(saver.back(),saver[saver.size()-2]);
}
};
class Solution {
public:
int rob(vector<int>& nums) {
int prevMax = 0;
int curMax = 0;
for(auto&i :nums){
int temp = curMax;
curMax = max(prevMax+i,curMax);
prevMax = temp;
}
return curMax;
}
};