leetcode---213. 打家劫舍 II
阿新 • • 發佈:2018-12-13
https://leetcode-cn.com/problems/house-robber-ii/
你是一個專業的小偷,計劃偷竊沿街的房屋,每間房內都藏有一定的現金。這個地方所有的房屋都圍成一圈,這意味著第一個房屋和最後一個房屋是緊挨著的。同時,相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。
給定一個代表每個房屋存放金額的非負整數陣列,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額。
輸入: [2,3,2]輸出: 3解釋: 你不能先偷竊 1 號房屋(金額 = 2),然後偷竊 3 號房屋(金額 = 2), 因為他們是相鄰的。
示例 2:輸入:
思路:dp很容易找到遞推公式。
但是形成環有點複雜,明白可以分為兩種情況,第一種(型別1)第一個元素不用,就可以訪問最後一個元素。第二種(型別2)是第一個使用,那麼就只能到倒數第二個。我考慮複雜了,一直思考存在一種情況,假設是第一個使用(型別2),但是到推到了倒數第二的時候可能的選擇是沒有搶第一個,這個是不是可以到再考慮最後一個呢。這種情況肯定包含在第一種情況裡。
class Solution { public: int rob(vector<int>& nums) { int n=nums.size(); vector<int> dp(n,0); int imax=0; if(n<1) return 0; if(n==1) return nums[0]; if(n==2) return max(nums[1],nums[0]); if(n==3) return max(nums[0],max(nums[1],nums[2])); if(n>=4) { //第一個不用 dp[0]=0; dp[1]=nums[1]; for(int i=2; i<n; i++) { dp[i]=max(dp[i-1],dp[i-2]+nums[i]); } imax=dp[n-1]; //第一個用 dp[0]=nums[0]; dp[1]=max(nums[1],nums[0]); for(int i=2; i<n-1; i++) { dp[i]=max(dp[i-1],dp[i-2]+nums[i]); } imax=max(imax,dp[n-2]); return imax; } } };