You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. All houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, 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: [2,3,2]
Output: 3
Explanation: You cannot rob house 1 (money = 2) and then rob house 3 (money = 2),
because they are adjacent houses.
Example 2:
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.
思路:
一、环形区域,考虑两种:
1. 第一家抢了,最后一家不能抢,范围是0~n-2
2. 第一家不抢,最后一家可以抢,范围是1-n-1
二、其余思路同robber i:
dp【i】表示 从 0 ~ n-1 能抢到的最大值,最后dp【end】为最终答案
dp【i】取决于两个值:
1. 如果这家抢,则dp【i】 = 上上家+这家抢的
2.如果这家不抢,则抢上一家为dp【i-1】
class Solution {
public:
int rob(vector<int>& nums) {
int n = nums.size();
if(n == 0) return 0;
if(n == 1) return nums[0];
if(n == 2) return max(nums[0], nums[1]);
return max(func(nums,0,n-2), func(nums,1,n-1));
}
int func(vector<int>& nums, int start, int end){
int n = end-start+1;
vector<int> dp(n);
dp[0] = nums[start];
dp[1] = max(nums[start], nums[start+1]);
for(int i = 2; i < n; i++){
dp[i] = max(dp[i-2]+nums[start+i], dp[i-1]);
}
return dp[n-1];
}
};