力扣198.打家劫舍(简单动态规划)

简介: 力扣198.打家劫舍(简单动态规划)

题目描述:

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警

给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

示例 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 。

提示:

  • 1 <= nums.length <= 100
  • 0 <= nums[i] <= 400

思路:

选择偷哪一个房子的钱其实就是01背包里的拿和不拿的问题,用一个一维的f[N]数组表示前i个房子能偷的最多的钱,为什么能用动态规划去解呢?因为状态具有传递性。也就是说可以列出来状态转移方程,每一个房子我都可以选择偷还是不偷,这么一来,所有的方案都考虑到了,满足dp的“不漏”这个要求。

这里的偷为什么是f[i]=nums[i]+f[i-2]?

因为根据题意,不能偷相邻房子的钱,如果你偷了第i个房子的钱,那么就不能算第i-1家的钱,只能加上偷前i-2栋房子最多的钱。

这里要注意边界问题,如果只有一间房子那么就直接能返回这个房子的钱,否则再考虑第二家房子的时候可能会出现问题。

如果对以上思路还不清楚的同学,可以去b站搜索y总的背包九讲,讲得非常详细,有兴趣的也可以去看看。

代码:

class Solution {
public:
    int rob(vector<int>& nums) {
        int len=nums.size();
        int  f[110]={0};
       for(int i=0;i<=len;i++)f[i]=0;
        f[0]=nums[0];
        if(len==1)return f[0];
        f[1]=max(f[0],nums[1]);
        for(int i=2;i<len;i++){
            f[i]=max(f[i-1],f[i-2]+nums[i]);
         }
         return f[len-1];
    }
};


相关文章
|
19天前
leetcode代码记录(打家劫舍 III
leetcode代码记录(打家劫舍 III
17 0
|
12天前
力扣740. 删除并获得点数(动态规划)
力扣740. 删除并获得点数(动态规划)
|
13天前
力扣337.打家劫舍3(树形dp)
力扣337.打家劫舍3(树形dp)
|
13天前
力扣213打家劫舍2(简单动态规划)
力扣213打家劫舍2(简单动态规划)
|
19天前
leetcode代码记录(打家劫舍 II
leetcode代码记录(打家劫舍 II
12 3
|
19天前
leetcode代码记录(打家劫舍
leetcode代码记录(打家劫舍
15 1
|
19天前
leetcode代码记录(动态规划基础题(斐波那契数列)
leetcode代码记录(动态规划基础题(斐波那契数列)
13 0
|
19天前
|
索引
力扣---最长回文子串(动态规划)
力扣---最长回文子串(动态规划)
|
19天前
[leetcode~数位动态规划] 2719. 统计整数数目 hard
[leetcode~数位动态规划] 2719. 统计整数数目 hard
|
19天前
|
算法
代码随想录算法训练营第五十六天 | LeetCode 647. 回文子串、516. 最长回文子序列、动态规划总结
代码随想录算法训练营第五十六天 | LeetCode 647. 回文子串、516. 最长回文子序列、动态规划总结
36 1