引言
uu们好,欢迎来到香菜的动态规划刷题记录专栏。接下来分享的思路&代码是力扣热题100中的动态规划的题目——198.打家劫舍。
如果有和香菜一样在学习动态规划的uu,可以点赞&收藏&关注插个眼,我们一起来学习、分享!
题目描述
力扣传送门——198. 打家劫舍 - 力扣(LeetCode)
题目描述:你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。题目要求:给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
思路分析
接下来按照我们在动态规划入门文章(本文末尾有其链接)中提到的明确数组的含义、找出数组元素之间的递推关系式、找出初始值(边界值处理)三个解题步骤进行分析。
- 明确数组的含义:题意很清晰,可以很直观的定义出数组,即dp[i] 代表考虑到第i个房屋时,在不触动报警装置的情况下,可以获得的最高金额。
- 找出数组元素间的递推关系式:从题目条件的介绍中,我们可以知道,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。也就是说当我们要面对第 i 间房屋时,此时是否选择进入房间取决于我们是否进入过第 i-1 间房屋,于是我们知道当前dp[i]的值应该受它前边dp[i-1]和dp[i-2]两个元素的影响,这就对应着两种情况,即我们偷窃过第 i-1 间房屋和我们没偷窃过第 i-1 间房屋。 对于第一种情况——偷窃过第 i-1 间房屋,那么根据题目条件的要求,我们无法对第 i 间房屋进行偷窃,因此 dp[i] = dp[i-1];对于第二种情况——我们未偷窃过第 i-1 间房屋,那么此时我们可以进入第 i 间房屋偷窃,则此时的dp[i] = dp[i-2] + value[i](假设每间房存放的金额数组为value)。综上以上两种情况可知,dp[i] = max(dp[i-1], dp[i-2] + value[i]);
- 找出初始值(边界值处理),很自然地,对于dp[0] = 0,即没有房屋可提供偷窃;dp[1] = value[1],对于只有一间房时,可偷窃的最大金额即为该间房屋内存放的金额。
代码
class Solution {
int dp[107] = {0};
public:
int rob(vector<int>& nums) {
int len = nums.size();
dp[1] = nums[0];
for(int i = 2; i<=len; i++){
dp[i] = max(dp[i-2] + nums[i-1], dp[i-1]);
}
return dp[len];
}
};