「动态规划」打家劫舍的变形题,你会做吗?

213. 打家劫舍 IIicon-default.png?t=N7T8https://leetcode.cn/problems/house-robber-ii/description/

你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都围成一圈,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,今晚能够偷窃到的最高金额。

  1. 输入:nums = [2,3,2],输出:3,解释:你不能先偷窃1号房屋(金额 = 2),然后偷窃3号房屋(金额 = 2), 因为他们是相邻的。
  2. 输入:nums = [1,2,3,1],输出:4,解释:你可以先偷窃1号房屋(金额 = 1),然后偷窃3号房屋(金额 = 3)。偷窃到的最高金额 = 1 + 3 = 4。
  3. 输入:nums = [1,2,3],输出:3。

提示:1 <= nums.length <= 100,0 <= nums[i] <= 1000。


本题在打家劫舍问题的基础上,加上了首尾相连的条件。解决本题的关键在于如何处理首尾相连的条件。假设有n个房屋。这里,我们根据偷不偷0位置的房屋,进行分类讨论:

  • 如果偷了0位置的房屋,那么就不能偷1位置和n - 1位置的房屋,此时问题转换为:房屋区间为[2, n - 2]的不含首位相连条件的打家劫舍问题。
  • 如果不偷0位置的房屋,此时问题转换为:房屋区间为[1, n - 1]的不含首位相连条件的打家劫舍问题。

而最终的结果,应该是这两种情况的较大值。好了,此时我们只需要解决不含首尾相连条件的打家劫舍问题。我们用动态规划的思想来解决这个问题,以下的讨论都不含首尾相连的条件。

确定状态表示:根据经验和题目要求,我们用dp[i]表示,考虑完i位置的房屋后,此时能偷到的最高金额。这又细分为:

  • 用f[i]表示:必须偷i位置的房屋,此时能偷到的最高金额
  • 用g[i]表示:不能偷i位置的房屋,此时能偷到的最高金额

推导状态转移方程:我们分别考虑2种情况中最近的一步,即是否偷i - 1位置的房屋。

  • 考虑f[i],由于必须偷i位置的房屋,所以不能偷i - 1位置的房屋。偷完i位置的房屋之后,能偷到的最高金额,就等于不能偷i - 1位置的房屋之后能偷到的最高金额加上i位置的房屋的金额,即f[i] = g[i - 1] + nums[i]。
  • 考虑g[i],由于不能偷i位置的金额,所以此时能偷到的最高金额就等于考虑完i - 1位置的房屋后能偷到的最高金额。由于不确定是否偷i - 1位置的房屋,所以结果是偷或者不偷i - 1位置的房屋这2种情况中,能偷到的最高金额的较大值,即g[i] = max(f[i - 1], g[i - 1])。

综上所述,f[i] = g[i - 1] + nums[i],g[i] = max(f[i - 1], g[i - 1])

初始化:根据状态转移方程,在填写f[0]和g[0]时,会发生越界访问,所以要对其初始化。

  • 如果必须偷0位置的房屋,那么此时能偷到的最高金额就是0位置的房屋的金额,即f[0] = nums[0]。
  • 如果不能偷0位置的房屋,那么此时能偷到的最高金额就是0,即g[0] = 0。

综上所述:f[0] = nums[0],g[0] = 0

填表顺序:根据状态转移方程,f[i]依赖于g[i - 1],g[i]依赖于f[i - 1]和g[i - 1],所以应从左往右同时填f表和g表

返回值:我们要求的是考虑完n - 1位置的房屋后,此时能偷到的最高金额,由于并不确定是否偷n - 1位置的房屋,所以结果是偷或者不偷n - 1位置的房屋这2种情况中,能偷到的最高金额的较大值,即max(f[n - 1], g[n - 1])

细节问题:回归题目本身。假设对于没有首尾相连条件的打家劫舍问题中,房屋区间是[left, right],能偷到的最高金额是rob(nums, left, right)。那么,最终的结果就是文章开头提到的2种情况的较大值,即max(nums[0] + rob(nums, 2, n - 2), rob(nums, 1, n - 1))。注意到下标几乎覆盖了整个nums数组,所以为了简单起见,我们把dp表的规模设置成和nums相同,即1 x n。此时,应初始化f[left] = nums[left],g[left] = 0,填表时应从left + 1位置开始一直填到right位置,最终应该返回max(f[right], g[right])

时间复杂度:O(N),空间复杂度:O(N)。

class Solution {
public:int rob(vector<int>& nums) {int n = nums.size();// 偷或者不偷0位置的房屋,这2种情况的较大值return max(nums[0] + rob(nums, 2, n - 2), rob(nums, 1, n - 1));}private:// 不含首尾相连条件的打家劫舍问题,房屋区间为[left, right]int rob(vector<int>& nums, int left, int right) {// 区间不存在if (left > right) {return 0;}int n = nums.size();// 创建dp表vector<int> f(n);auto g = f;// 初始化f[left] = nums[left];// 填表for (int i = left + 1; i <= right; i++) {f[i] = g[i - 1] + nums[i];g[i] = max(f[i - 1], g[i - 1]);}// 返回结果return max(f[right], g[right]);}
};

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

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

相关文章

使用 Vue 官方脚手架初始化 Vue3 项目

Vite 官网&#xff1a;https://cn.vitejs.dev/ Vue 官网&#xff1a;https://vuejs.org/ Vue 官方文档&#xff1a;https://cn.vuejs.org/guide/introduction.html Element Plus 官网&#xff1a;https://element-plus.org/ Tailwind CSS 官网&#xff1a;https://tailwindcss.…

Codeforces Round 951 (Div. 2)C. Earning on Bets

Problem - C - Codeforces 合理的答案&#xff1a; 求出 k1 ~ kn 的最小公倍数lcm&#xff0c;如果 lcm/k1 lcm/k2 ... lcm/kn < lcm 即符合题意。 左边之和为我们付的总钱数&#xff0c;右边才是每次选择得到的钱数(都为lcm)。 直接拿1e9检查是否可以分即可&#xff…

基于Django+MySQL的智慧校园系统

此项目基于Django MySQL HTML CSS JS jQuery bootstrap实现的功能有 学生管理部门管理代办清单管理校园论坛校园医疗服务校园看点校园生活助手常用功能入口 1. 一些注意点 1. 页面body会自动有一些边界距&#xff0c;处理方法&#xff1a; <head><style>b…

你还在纠结U盘怎么选吗?小白带你来看

前言 2024年的618活动已经开始了&#xff0c;这个活动买电子产品着实是比其他时间要便宜很多。 前几天小白的一个好朋友问我&#xff1a;U盘该怎么选&#xff1f; 呃&#xff0c;本来是想写“老朋友”的&#xff0c;结果她愣是要我改成“好朋友”。 行吧&#xff0c;那就好朋…

车载电子电气架构 --- 车载信息安全

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节…

Vite - 开发初体验,以及按需导入配置

目录 开始 创建一个 Vite 项目 项目结构 /src/main.js index.html package.json vite.config.js Vite 项目中使用 vue-router Vite 组件的“按需引入” 传统的方式引入一个组件 传统方式引入带来的问题 解决办法&#xff08;配置 按需引入 插件&#xff09; 示例&…

OpenFeign远程接口调用使用公共模块出现的错误

今天在使用openfeign和sentinel实现fallback服务降级时遇到找不到类型的异常 检查代码发现没有错误&#xff0c;EnableFeignClients也在启动类上标注了 错误信息&#xff1a;A component required a bean of type com.zxc.cloud.apis.PayFeignSentinelApi that could not be f…

《精通ChatGPT:从入门到大师的Prompt指南》第9章:实战练习

第9章&#xff1a;实战练习 9.1 Prompt练习题 在本节中&#xff0c;我们将提供一系列练习题&#xff0c;旨在帮助读者通过实际操作提升使用ChatGPT的能力。这些练习题涵盖了从基础到高级的不同难度级别&#xff0c;并针对各种应用场景设计&#xff0c;确保读者能够在实际使用…

基于Springboot + vue实现的火锅店管理系统

作者主页&#xff1a;Java码库 主营内容&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】&#xff1a;Java 【框架】&#xff1a;spring…

私有云和多云管理平台 | Cloudpods v3.11.4 正式发布

本次 3.11.4 更新亮点为&#xff1a;系统镜像引入社区镜像&#xff0c;用户可以一键导入各主流开源操作系统镜像&#xff0c;方便用户上手使用。持续迭代共享 LVM&#xff0c;支持快照&#xff0c;主备机等特性&#xff0c;修复迁移删除镜像缓存等 BUG。 功能优化 【费用】费…

EON安装ASE Interface

安装 测试系统ubuntu。如果你python2和python3总是纠缠不清&#xff0c;可以sudo apt install python-is-python3直接解决。 经检查&#xff0c;我PC的 python地址为&#xff1a; /usr/include/python3.8/ pybind11地址为&#xff1a; /usr/include/pybind11/ 已确认python…

AE电源pinnacle软件新款老款二款软件

AE电源pinnacle软件新款老款二款软件

C++从入门到精通(最详细教程,12万总结,带你掌握c++知识,涵盖大量知识点)

目录 一、面向对象的思想 二、类的使用 1.类的构成 2.类的设计 三、对象的基本使用 四、类的构造函数 1.构造函数的作用 2.构造函数的特点 3.默认构造函数 3.1.合成的默认构造函数 3.2.手动定义的默认构造函数 四、自定义的重载构造函数 五、拷贝构造函数 1.手动…

联合体和枚举<C语言>

导言 在C语言中除了结构体外&#xff0c;联合体和枚举也是自定义类型&#xff0c;联合体主要用于节省空间&#xff0c;在同一块内存存储多种类型的数据&#xff0c;而枚举可以提高代码的可读性、可维护性。 联合体&#xff08;union&#xff09; 它还有个更容易理解的名字&…

适用于电脑的 5 大嗨格式数据恢复替代方案

嗨格式数据恢复是有一定知名度的 Windows 和 Mac 恢复程序&#xff0c;旨在恢复格式化、删除和丢失的图片、视频和音频。该应用程序支持多种文件格式以及相机 RAW 图像。最好的部分&#xff1f;它的预览功能可以在恢复照片和其他媒体文件之前检查和验证它​​们——这可以节省大…

番外篇 | 超越ReLU却鲜为人知,YOLOv5改进之崛起的最佳激活函数GELU!

前言:Hello大家好,我是小哥谈。作为决定神经网络是否传递信息的「开关」,激活函数对于神经网络而言至关重要。不过今天被人们普遍采用的ReLU真的是最高效的方法吗?最近在社交网络上,人们找到了一个看来更强大的激活函数:GELU,这种方法早在2016年即被人提出,然而其论文迄…

快排(快速排序)的递归与非递归实现(文末附完整代码)

快排有几种不同的写法&#xff0c;下面一一来介绍并实现。其中又分为递归和非递归的写法&#xff0c;但大体思路相同&#xff0c;只是代码实现略有不同。(注&#xff1a;文章中的完整代码中&#xff0c;Swap()函数均省略未写&#xff0c;记得自己补充) 递归写法 递归的写法类…

glm-4v-9b 部署

glm-4v-9b 模型文件地址 GLM-4 仓库文件地址 官方测试 硬件配置和系统要求 官方测试硬件信息: OS: Ubuntu 22.04Memory: 512G…

进程概念(二)

目录 进程优先级基本概念查看系统进程PRI and NIPRI vs NI修改进程优先级的命令renice修改优先级进程其他概念 环境变量基本概念查看环境变量方法常见环境变量PATHHOMESHELL 查看环境变量环境变量相关的命令 环境变量特征命令行参数main函数中的俩个参数 argc argvmain函数的第…

LabVIEW缝缺陷图像标注库

LabVIEW缝缺陷图像标注库 开发了一个基于LabVIEW平台构建的船舶焊缝缺陷图像标注库。该库旨在通过高效和简洁的方式处理和标注船舶焊缝缺陷图像&#xff0c;提高缺陷识别的准确性和效率&#xff0c;进而保障船舶的结构安全。 项目背景 在船舶制造过程中&#xff0c;焊接质量…