LeetCode198.打家劫舍

题目

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

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

示例

输入:[1,2,3,1]

输出:4

解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。

偷窃到的最高金额 = 1 + 3 = 4 。
输入:[2,7,9,3,1]

输出:12

解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。

偷窃到的最高金额 = 2 + 9 + 1 = 12 。

思路

这是一个经典的动态规划问题,通常被称为 "打家劫舍" 问题。在不触动警报装置的情况下偷窃最高金额,可以使用动态规划的方法来解决。

首先考虑最简单的情况。如果只有一间房屋,则偷窃该房屋,可以偷窃到最高总金额。如果只有两间房屋,则由于两间房屋相邻,不能同时偷窃,只能偷窃其中的一间房屋,因此选择其中金额较高的房屋进行偷窃,可以偷窃到最高总金额。

如果房屋数量大于两间,应该如何计算能够偷窃到的最高总金额呢?对于第 k (k>2) 间房屋,有两个选项:

  • 偷窃第 k 间房屋,那么就不能偷窃第 k−1 间房屋,偷窃总金额为前 k−2间房屋的最高总金额与第 kkk 间房屋的金额之和。

  • 不偷窃第 k 间房屋,偷窃总金额为前 k−1 间房屋的最高总金额。

在两个选项中选择偷窃总金额较大的选项,该选项对应的偷窃总金额即为前 k 间房屋能偷窃到的最高总金额。

假设 dp[i] 表示偷取前 i 个房屋能够获得的最高金额,那么状态转移方程可以定义如下:

dp[i] = max(dp[i-1], dp[i-2] + nums[i])

其中,dp[i-1] 表示不偷第 i 个房屋时能够获得的最高金额,dp[i-2] + nums[i] 表示偷取第 i 个房屋时能够获得的最高金额(因为不能偷相邻的房屋,所以要加上 i-2 位置的金额)。

Code

cpp 复制代码
class Solution {
public:
    int rob(vector<int>& nums) {
        int n = nums.size();
        if(n==1)return nums[0];
        vector<int>dp(n);
        dp[0]=nums[0];
        dp[1]=max(dp[0],nums[1]);
        for(int i=2;i<n;i++)
        {
            dp[i] = max(dp[i-1],dp[i-2]+nums[i]);
        }
        return dp[n-1];
    }
};
相关推荐
炸膛坦客18 小时前
嵌入式 - 数据结构与算法:(1-10)排序算法 - 冒泡排序(Bubble Sort)
算法·排序算法
salipopl18 小时前
C++ 面试题:C++中 constexpr 函数的限制有哪些?
c++
无限进步_18 小时前
【C++】从红黑树到 map 和 set:封装设计与迭代器实现
开发语言·数据结构·数据库·c++·windows·github·visual studio
Hello eveybody18 小时前
介绍一下动态树LCT(Python)
开发语言·python·算法
不穿铠甲的穿山甲18 小时前
MMR最大边际相关性
算法
handler0118 小时前
速通蓝桥杯省一:二分算法
c语言·开发语言·c++·笔记·算法·职场和发展·蓝桥杯
炽烈小老头18 小时前
【 每天学习一点算法 2026/05/08】最小覆盖子串
学习·算法
汉克老师19 小时前
GESP5级C++考试语法知识(十六、分治算法(三))
c++·算法·分治算法·汉诺塔·逆序对·gesp5级·gesp五级
V搜xhliang024619 小时前
OpenClaw进阶完全教程
运维·人工智能·算法·microsoft·自动化
hele_two19 小时前
SDL2设置透明度
c++·图形渲染