你是一個專業的小偷,計劃偷竊沿街的房屋。每間房內都藏有一定的現金,
影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,
如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。
給定一個代表每個房屋存放金額的非負整數數組,計算你在不觸動警報裝置
的情況下,能夠偷竊到的最高金額。
示例 1:
輸入: [1,2,3,1]
輸出: 4
解釋: 偷竊 1 號房屋 (金額 = 1) ,然後偷竊 3 號房屋 (金額 = 3)。
偷竊到的最高金額 = 1 + 3 = 4 。
示例 2:
輸入: [2,7,9,3,1]
輸出: 12
解釋: 偷竊 1 號房屋 (金額 = 2), 偷竊 3 號房屋 (金額 = 9),接着偷竊 5 號房屋 (金額 = 1)。
偷竊到的最高金額 = 2 + 9 + 1 = 12 。
方法:動態規劃思想,dp[n] 表示前n個房子所獲最大收益,第n個房子可能是第n - 2個房子過來或第 n - 3個房子過來,比如 2 1 1 5 這種情況,不可能隔三個,因爲中間的白給,所以
dp[n] = max(dp[n - 2], dp[n - 3]) + nums[n]
class Solution {
public int rob(int[] nums) {
int len = nums.length;
if(len == 0) return 0;
if(len == 1) return nums[0];
if(len == 2) return Math.max(nums[0], nums[1]);
if(len == 3) return Math.max(nums[0] + nums[2], nums[1]);
int[] dp = new int [len + 1];
dp[0] = nums[0];
dp[1] = nums[1];
dp[2] = nums[2] + dp[0];
int ans = Math.max(dp[1], dp[2]);
for(int i = 3; i < len; i++){
dp[i] = Math.max(dp[i - 2], dp[i - 3]) + nums[i];
ans = Math.max(ans, dp[i]);
}
return ans;
}
}
更簡單的轉移方程:dp[n] = max( dp[n-1], dp[n-2] + nums[n])
class Solution {
public int rob(int[] nums) {
int len = nums.length;
if(len == 0) return 0;
int[] dp = new int[len + 1];
dp[0] = 0;
dp[1] = nums[0];
for(int i = 2; i <= len; i++){
dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i - 1]);
}
return dp[len];
}
}