Note: This is an extension of House Robber.
After robbing those houses on that street, the thief has found himself a new place for his thievery so that he will not get too much attention. This time, all houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, the security system for these houses remain the same as for those in the previous street.
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.
====================================================================================================================================这道题目跟leetcode198题的意思差不多,只是多了一个条件。其大意是:一个小偷要去一条(环形)街道偷东西,每间房子都有一定数量的金钱,但小偷不能偷任意相连的两间房子的金钱,不然就会触发警报系统。求小偷在不触发警报系统情况下能偷到的最大金额。
这个题目也是一个简单的DP问题。用dp[i]表示从0到i房子中能偷到的最大金额,则当i>=2时,dp[i] = max ( dp[i-1] , dp[i-2] + nums[i] ),只是这道题有个条件就是该街道是环形的,意思就是0和n-1号房间是相连的,所以我们的结果不能同时包含0和n-1号房间的金额,因此我们计算的时候要保证它们俩的不同时出现。在这里我用的是计算从0到n-2和从1到n-1两种方式的最大值,这样就能避免0和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] ;
if ( n == 2 )
return max ( nums[0] , nums[1] ) ;
int dp1[n-1] = {0} ;
dp1[0] = nums[0] ;
dp1[1] = max ( nums[0] , nums[1] ) ;
for ( int i = 2 ; i < n - 1 ; i ++ )
dp1[i] = max ( dp1[i-1] , dp1[i-2] + nums[i] ) ;
int dp2[n-1] = {0} ;
dp2[0] = nums[1] ;
dp2[1] = max ( nums[1] , nums[2] ) ;
for ( int i = 2 ; i < n - 1 ; i ++ )
dp2[i] = max ( dp2[i-1] , dp2[i-2] + nums[i+1] ) ;
return max ( dp1[n-2] , dp2[n-2] ) ;
}
};