题干;
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额
示例;
输入:[1,2,3,1]
输出:4
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
偷窃到的最高金额 = 1 + 3 = 4 。
public class 打家劫舍 {
public static void main(String[] args) {
int[] nums = {2,1,1,2};
System.out.println(rob(nums));
}
public static int rob(int[] nums) {
switch (nums.length){
case 0: return 0;
case 1: return nums[0];
default:
int[] dp = new int[nums.length+1];
dp[0] = 0;
dp[1] = nums[0];
for(int i=2;i<=nums.length;i++){
dp[i] = Math.max(dp[i-1],nums[i-1]+dp[i-2]);
}
return dp[nums.length];
}
}
}
动态规划,假设原问题是打劫n个房屋最多能拿多少钱,那么子问题就是打劫前k个房屋最多能拿多少钱,dp[i]表示打劫前i个房屋最多能拿到的钱数,那么需要理解的就是这个递推公式,我们在选择打劫房屋的时候有两种情况,一种是打劫最后一间房屋获得nums[i-1],然后再加上前i-2个房屋最大能拿到的钱数(最后一间房屋前面的一件不能打劫);第二种是不打劫最后一间房,选择前i-1间房屋进行打劫,也就是dp[i-1]。二者的最大值就是我们要求的每个子问题的解,再返回dp[nums.length]就是原问题的解。