力扣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
from typing import Listclass Solution:def rob(self, nums: List[int]) -> int:# 如果房屋数量为 0,直接返回 0,因为没有房子可偷if len(nums) == 0:return 0# 如果房屋数量为 1,返回唯一一间房屋的金额if len(nums) == 1:return nums[0]# 如果房屋数量为 2,返回两者中较大的金额if len(nums) == 2:return max(nums[0], nums[1])# 创建一个 dp 数组,其中 dp[i] 表示偷到第 i 间房屋时能获取的最大金额dp = [0] * len(nums)# 初始化前两间房屋的最大偷窃金额dp[0] = nums[0]  # 第一间房屋只能偷它自己dp[1] = max(nums[0], nums[1])  # 第二间房屋可以选择偷第一间或第二间,取金额较大者# 从第 3 间房屋开始,计算每间房屋的最大偷窃金额for i in range(2, len(nums)):# 对于第 i 间房屋,可以选择:# 1. 偷它,并加上偷第 i-2 间房屋的最大金额(因为相邻房屋不能同时偷)# 2. 不偷它,直接取第 i-1 间房屋的最大金额dp[i] = max(dp[i-2] + nums[i], dp[i-1])# 返回最后一间房屋对应的最大偷窃金额,即为结果return dp[-1]

解释:

  1. 特殊情况处理

    • 如果房屋数量为 0,则返回 0,因为没有房屋可以偷。
    • 如果房屋数量为 1,则返回第一个房屋的金额,因为只能偷这一间。
    • 如果房屋数量为 2,则只能偷其中金额较大的一间,因此返回这两者中的最大值。
  2. 动态规划数组 dp

    • dp[i] 代表到达第 i 间房屋时,小偷能偷到的最大金额。
    • 初始化 dp[0] 为第一个房屋的金额,dp[1] 为前两间房屋中金额较大的值。
  3. 动态规划递推

    • 对于每一间房屋,从第 3 间开始(即下标为 2 的房屋),有两种选择:
      1. 偷这一间房屋,加上第 i-2 间房屋的最大金额。
      2. 不偷这一间房屋,取前一间房屋的最大金额。
    • 在这两者中选择较大的值更新 dp[i],保证每一步都获得最大金额。
  4. 结果返回

    • dp[-1] 即为偷窃到最后一间房屋时的最大金额,也就是最终答案。

dp 是动态规划(Dynamic Programming)的简称,它是一种常见的算法设计思想,用来解决具有重叠子问题和最优子结构的问题。动态规划通过将问题分解为更小的子问题,记录这些子问题的解,然后根据这些子问题的解来构造出原问题的解,从而避免重复计算。

在这个小偷问题中,dp 是一个数组,用来存储每个子问题的最优解,具体来说:

  • dp[i] 表示到达第 i 间房屋时,能够偷到的最大金额。这个数组记录了在每个房屋时,如何做出选择(偷还是不偷),使得偷窃的总金额最大。

动态规划的关键概念:

  1. 重叠子问题: 动态规划适用于那些可以通过递归或分解为相似的子问题解决的情况。比如,在小偷问题中:

    • 如果你决定偷第 i 间房屋,那么你还需要知道偷第 i-2 间房屋能得到的最大金额(因为相邻的房子不能同时偷)。
    • 如果你不偷第 i 间房屋,那么你只需要知道偷第 i-1 间房屋的最大金额。
  2. 最优子结构: 问题的整体最优解可以由其子问题的最优解构成。在这个问题中,偷窃第 i 间房屋的最优解可以通过第 i-2 间房屋和第 i-1 间房屋的最优解推导出来。

举个例子解释 dp 的含义:

假设房屋里的金额是 [2, 7, 9, 3, 1],小偷希望能偷到最多的钱但不能偷相邻的房子。

  • dp[0] = 2:表示只看第 1 间房屋时,最多能偷 2 元。
  • dp[1] = 7:表示只看前两间房屋时,最多能偷 7 元(因为第 2 间房屋钱更多,偷第 1 间房屋不划算)。
  • dp[2] = max(dp[0] + nums[2], dp[1]) = max(2 + 9, 7) = 11:表示到第 3 间房屋时,可以选择偷第 1 间和第 3 间房屋(共 2 + 9 = 11 元),或者只偷前两间房屋(共 7 元),所以偷第 1 和第 3 间房屋的总金额最大。
  • dp[3] = max(dp[1] + nums[3], dp[2]) = max(7 + 3, 11) = 11:到第 4 间房屋时,最优解是保持偷前 3 间房屋的最大金额(11 元),因为偷第 2 间和第 4 间的金额不比之前多。
  • dp[4] = max(dp[2] + nums[4], dp[3]) = max(11 + 1, 11) = 12:到第 5 间房屋时,最优解是偷第 1、3、5 间房屋,总金额为 12 元。

动态规划公式:

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

这个公式的意思是,对于每一间房屋 i,你有两个选择:

  1. 偷它,然后加上两间前房屋(i-2)的最大偷窃金额。
  2. 不偷它,只取前一间房屋(i-1)的最大偷窃金额。

通过这样递推计算,我们可以得出小偷能在不触发警报的情况下,偷窃的最高金额。

总结:

  • dp 是动态规划的核心工具,它用于存储每个子问题的最优解。
  • 动态规划方法通过分解问题,利用以前的结果,避免了重复计算,使得算法更高效。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/54226.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

下载Kafka 3.0.0教程

1、Kafka 3.0.0下载地址 Apache Kafka 2、往下拉&#xff0c;查找3.0.0版本点击下载

python测试开发---css基础

CSS&#xff08;Cascading Style Sheets&#xff0c;层叠样式表&#xff09;是用于描述 HTML 或 XML 文档的外观和格式的语言。它可以控制网页元素的布局、颜色、字体等样式&#xff0c;使页面更美观和易用。下面是 CSS 基础的介绍&#xff0c;包括语法和常用的属性。 1. CSS …

(PySpark)RDD实验实战——取最大数出现的次数

实验环境&#xff1a; 提前准备好findspark&#xff0c;pyspark&#xff0c;py4j等库import findspark from pyspark import SparkContext, SparkConffindspark.init() #初始化spark&#xff0c;默认为你所设定的环境变量 conf SparkConf().setAppName("jsytest")…

React——setState 新旧值复用问题

异步状态更新获取新值问题 问题解决 问题 const updateFrameRange (frameNumber, rangeValue) > {//const startFrame Math.max(frameNumber - rangeValue.before, 1);const endFrame Math.min(frameNumber rangeValue.after, maxFrame); console.log(frameNumber,rang…

【C++前后缀分解 降维】2906. 构造乘积矩阵|2074

前后缀分解 C前后缀分解 LeetCode2906. 构造乘积矩阵 给你一个下标从 0 开始、大小为 n * m 的二维整数矩阵 grid &#xff0c;定义一个下标从 0 开始、大小为 n * m 的的二维矩阵 p。如果满足以下条件&#xff0c;则称 p 为 grid 的 乘积矩阵 &#xff1a; 对于每个元素 p[…

使用python 将world的题库导入某学习软件的模板

本python中使用了模块&#xff1a; re:用于写正则 python-docx&#xff1a;用于读取worl中的数据 openpyxl&#xff1a;用于将内容写入excel -----------------------------------------前言----------------------------------------------- 此代码仅可以使用&#xff0c…

数据结构之‘栈’

文章目录 1.简介2. 栈的初始化和销毁3. 进栈和出栈3.1 进栈3.2 出栈3.3 栈的打印 1.简介 一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行&#xff08;数据插入和删除操作&#xff09;的一端称为栈顶&#xff0c;另一端称为栈底。压栈&#xf…

C语言之预处理详解(完结撒花)

目录 前言 一、预定义符号 二、#define 定义常量 三、#define定义宏 四、宏与函数的对比 五、#和## 运算符 六、命名约定 七、#undef 八、条件编译 九、头文件的包含 总结 前言 本文为我的C语言系列的最后一篇文章&#xff0c;主要讲述了#define定义和宏、#和##运算符、各种条件…

W25QXX系列Flash存储器模块驱动代码

目录 W25QXX简介 硬件电路 W25Q128框图 Flash操作注意事项 驱动代码 W25QXX.h W25QXX.c W25QXX简介 W25Qxx系列是一种低成本、小型化、使用简单的非易失性存储器&#xff0c;常应用于数据存储、字库存储、固件程序存储等场景 存储介质&#xff1a;Nor Flash&#xff0…

算法入门-贪心1

第八部分&#xff1a;贪心 409.最长回文串&#xff08;简单&#xff09; 给定一个包含大写字母和小写字母的字符串 s &#xff0c;返回通过这些字母构造成的最长的回文串 的长度。 在构造过程中&#xff0c;请注意 区分大小写 。比如 "Aa" 不能当做一个回文字符串…

如何通过 PhantomJS 模拟用户行为抓取动态网页内容

引言 随着网页技术的不断进步&#xff0c;JavaScript 动态加载内容已成为网站设计的新常态&#xff0c;这对传统的静态网页抓取方法提出了挑战。为了应对这一挑战&#xff0c;PhantomJS 作为一个无头浏览器&#xff0c;能够模拟用户行为并执行 JavaScript&#xff0c;成为了获…

Android RecycleView 深度解析与面试题梳理

本文首发于公众号“AntDream”&#xff0c;欢迎微信搜索“AntDream”或扫描文章底部二维码关注&#xff0c;和我一起每天进步一点点 引言 在 Android 开发中&#xff0c;列表和网格布局是非常常见的界面元素&#xff0c;它们用于展示大量数据集合。RecyclerView 是 Android 提…

小众语言ruby在苹果中的初步应用

前言 感觉Ruby在苹果系统中充当一种脚本语言来使用。 1、直接输入ruby没有反应 2、可显示结果的命令 ruby -e "puts Goodbye, cruel world!" 效果如下图&#xff1a; 说明苹果系统中ruby已经安装完毕&#xff0c;或者就是自带的。 3、编辑运行第一个ruby程序 输入…

nodejs+express+vue教辅课程辅助教学系统 43x2u前后端分离项目

目录 技术栈具体实现截图系统设计思路技术可行性nodejs类核心代码部分展示可行性论证研究方法解决的思路Express框架介绍源码获取/联系我 技术栈 该系统将采用B/S结构模式&#xff0c;开发软件有很多种可以用&#xff0c;本次开发用到的软件是vscode&#xff0c;用到的数据库是…

MySQL学习(视图总结)

文章目录 MySQL的视图视图基本操作创建视图修改视图 练习 MySQL的视图 视图是虚拟的表&#xff0c;是从数据库中一个或多个表中导出来的表&#xff0c;作用是可以隐藏一些数据&#xff0c;也可以将一些复杂的查询结果做成视图。数据库只保存视图的定义&#xff0c;而不保存视图…

运维最难的是哪些部分呢

在讨论运维工作中&#xff0c;监控通常被视为一个核心且至关重要的环节&#xff0c;但它是否可以被简单地定义为“最难”的工作&#xff0c;则取决于多种因素&#xff0c;包括但不限于技术复杂度、资源投入、团队结构、业务特性以及故障应对的及时性等。以下是对运维中监控工作…

基因组注释工具MAKER的报错与解决方法

基因组注释工具MAKER的报错与解决措施 ● 报错1 ● 报错内容&#xff1a;ERROR: Could not determine if DFam is installed ● 解决措施&#xff1a; ● export LIBDIR/your_path/envs/maker/share/RepeatMasker/Matrices ● export LIBDIR/your_path/envs/maker/share/R…

Linux常见查看文件命令

目录 一、cat 1.1. 查看文件内容 1.2. 创建文件 1.3. 追加内容到文件 1.4. 连接文件 1.5. 显示多个文件的内容 1.6. 使用管道 1.7. 查看文件的最后几行 1.8. 使用 -n 选项显示行号 1.9. 使用 -b 选项仅显示非空行的行号 二、tac 三、less 四、more 五、head 六、…

解决Gson将长数字( json字符串)转换为科学记数法格式

Gson&#xff08;又称Google Gson&#xff09;是Google公司发布的一个开放源代码的Java库&#xff0c;主要用途为序列化Java对象为JSON字符串&#xff0c;或反序列化JSON字符串成Java对象。 依赖 Gradle: dependencies {implementation com.google.code.gson:gson:2.11.0 }…

sql中行转列 列转行

场景 在平常使用中&#xff0c;我们经常会遇到行专列&#xff0c;列转行进行查询的操作 或者 一行转多列的情况 我们接下来讨论如何通过一条语句实现&#xff0c;动态sql创建的方式暂时除外&#xff0c;当然你可以可以使用动态sql创建为存储过程&#xff0c;我会介绍几种常用…