你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
示例 1:
输入:[1,2,3,1] 输出:4 解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。 偷窃到的最高金额 = 1 + 3 = 4 。
首先让我们牢记动态规划四部曲:
- dp数组定义,含义
- 递推公式
- 初始化
- 遍历顺序
很显然我们要求偷窃到的最高金额,我们的dp数组就要维护一个数组记录到目前偷到的最高金额。
递推公式我们可以这样来看dp[i]要么是i-2偷完了来偷你了,要么就是i-3偷完了i-1不惜的偷来偷你了
那么我们的递推就要加上一层比较到底偷不偷你上家,
dp[i]=Math.max(dp[i-2]+nums[i-1],dp[i-3]+nums[i-1]);
初始化:你看要有i-3和i-2了我们就得从3开始递推了,前面都当赠送条件了
class Solution {
public int rob(int[] nums) {
int n =nums.length;
if(n<=1){
return nums[0];
}
int[] dp = new int[n+1];
dp[0] = 0;
dp[1] = nums[0];
dp[2] = nums[1];
for(int i = 3;i<=n;i++){
dp[i]=Math.max(dp[i-2]+nums[i-1],dp[i-3]+nums[i-1]);
}
return Math.max(dp[n],dp[n-1]);
}
}
你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警 。
给定一个代表每个房屋存放金额的非负整数数组,计算你 在不触动警报装置的情况下 ,今晚能够偷窃到的最高金额。
示例 1:
输入:nums = [2,3,2] 输出:3 解释:你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的。
这个问题还是比上面多了一层操作 , 因为第一个和最后一个不能挨着,那么我们换一种想法就是,把第一个和最后一个分开算,算完再比一下大小就OK
就把上面的封装一下,封装成一个方法,然后传进去比较。
class Solution {
public int rob(int[] nums) {
int n = nums.length;
if(n == 0) return 0;
if(n == 1) return nums[0];
return Math.max(rob(nums,0,n-2),rob(nums,1,n-1));
}
int rob(int[] nums,int start,int end){
if (end == start) return nums[start];
int[] dp = new int[nums.length];
dp[start] = nums[start];
dp[start+1] = Math.max(nums[start],nums[start+1]);
for(int i = start+2;i<=end;i++){
dp[i] = Math.max(dp[i-2]+nums[i],dp[i-1]);
}
return dp[end];
}
}
标签:偷窃,213,nums,int,leetcode198,start,房屋,打家劫舍,dp
From: https://blog.csdn.net/weixin_74047328/article/details/145231517