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 间房屋能偷窃到的最高总金额。

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

dpi = max(dpi-1, dpi-2 + numsi)

其中,dpi-1 表示不偷第 i 个房屋时能够获得的最高金额,dpi-2 + numsi 表示偷取第 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];
    }
};
相关推荐
悠仁さん6 小时前
【C++】AVL 树
c++
wuminyu6 小时前
JVM规范学习总结:解释器与JIT编译器如何处理JVM字节码
java·linux·c语言·jvm·c++
小徐不徐说6 小时前
序列化与反序列化:把 C++ 对象可靠地保存下来
开发语言·数据库·c++·php
ZhengEnCi6 小时前
模型训练完整流程:从数据准备到模型上线的 10 个关键步骤(全文可跑)
后端·算法
ragnwang7 小时前
Notes: Python pybind11 import C++ module
开发语言·c++·python
充值内卷8 小时前
我给桌面加了个鱼缸:C++ 写后端,WebView2 里养一座 Three.js 小岛
开发语言·javascript·c++
吞下星星的少年·-·10 小时前
Div.3 CF 1131A题(排序,模拟)
算法·模拟·排序
圣保罗的大教堂10 小时前
leetcode 453. 最小操作次数使数组元素相等 中等
leetcode
aichitang202411 小时前
代数拓扑学与现代前沿视角
考研·算法·数学建模·ai·拓扑学·高考