题目如下:
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
首先定义dp数组 并理清dp数组的含义:dp[i] 表示偷到第i家(包括第i家)能偷的最多偷窃金额
状态转移方程的确定:对于每一家,其实只有偷与不偷两种情况,所以偷到这家时能获得的最多偷窃金额就是在这两种情况下所能获得的最大值。
①偷的话,那上一家肯定是不能偷的,所以这种情况下所能获得的金额为dp[i-2] + nums[i].
②不偷的话,这种情况下所能获得的金额就跟偷到上一家获得的金额一样,为dp[i-1]
所以状态转移方程为:dp[i] = Math.max(dp[i-2] + nums[i], dp[i-1])
js实现:
/**
* @param {number[]} nums
* @return {number}
*/
var rob = function( nums ) {
// dp[i] 表示偷到第i家(包括第i家)最多的偷窃金额
let dp = Array(nums.length).fill(0);
dp[0] = nums[0];
if(nums.length >= 2) {
dp[1] = Math.max(nums[0], nums[1]);
}
for(let i = 2; i < nums.length; i++) {
// 取 ‘偷’还是‘不偷’这两种情况的最大值
dp[i] = Math.max(nums[i]+dp[i-2], dp[i-1]);
}
return dp[nums.length-1];
};
java实现:
class Solution {
public int rob(int[] nums) {
if (nums == null || nums.length == 0) {
return 0;
}
int length = nums.length;
if (length == 1) {
return nums[0];
}
int[] dp = new int[length];
dp[0] = nums[0];
dp[1] = Math.max(nums[0], nums[1]);
for (int i = 2; i < length; i++) {
dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]);
}
return dp[length - 1];
}
}