Problem: 213. 打家劫舍 II
思路
此题在198. 打家劫舍的基础了稍微进行了调整,数组的第一个和最后一个房子不能同时打劫,如果不打劫最后一个房子,则变得与198题相同,这样是一种情况;其它还有的情况:第一个房子不打劫,这样也简化为198题的情况。那么可以从[0, n-2]
和[1, n-1]
分别进行动态规划,取最大值。
动态规划实现:dp下标含义打劫到i时的最大钱数。dp递推公式在nums[i]
这里(向前推测):要么打劫nums[i-1]
,要么打劫nums[i-2]
+nums[i]
。dp赋初值,需要对dp[0]
,dp[1]
确定初值的含义,dp[0]=nums[0]
, dp[1]
不能简单等于nums[1]
因为这样就可能破坏了递推公式(如测试样例[2,1,1,2]
),dp[1]
应该为nums[0]
与nums[1]
中最大值(这样正好符合上面的递推公式)。再进行样例手动模拟,确定思路的正确。
Code
class Solution {
public:
int robRange(vector<int>& nums, int start, int end)
{
if(start==end) return nums[start];
vector<int> dp(nums.size(), 0);
dp[start] = nums[start];
dp[start+1] = max(nums[start+1], nums[start]);
for(int i = start + 2; i <= end; ++i)
{
dp[i] = max( dp[i-2]+nums[i], dp[i-1] );
}
return dp[end];
}
int rob(vector<int>& nums) {
int n = nums.size();
if(n == 1) return nums[0];
int result1 = robRange(nums, 0, n-2);
int result2 = robRange(nums, 1, n-1);
return max(result1, result2);
}
};