动态规划——打家劫舍(C++)

好像,自己读的书确实有点少了。

——2024年7月2日


198. 打家劫舍 - 力扣(LeetCode)

题目描述

        你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

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

题解思路

        动态规划

        利用动态规划解题的时候,dp数组的含义都是自己定的,定好之后就需要思考自己如何实现,列出状态转移方程,题目就迎刃而解了。

 解法一

1. 定义dp数组含义;

        dp[i]表示偷取以 i 结尾的房间能够获取的最大价值。

2. 根据dp含义列出状态转移方程;

        因为小偷不能偷取连续的两个房间,那么如果偷取了第 i 个房间,第 i-1 间房间就不能偷取了,否则会触发警报,但是 i-2 以前的所有房间都是可以偷取的,所以列出状态转移方程如下:
        dp[i] = max( dp[0], dp[1], ..., dp[i - 2] ) + nums[i];

3. 确定边界条件;

        ①如果只有一个房间,那么dp[0] = nums[0];
        ②如果只有两个房间,那么dp[1] = max(nums[0], nums[1]);

4.思考实现方式;

        对于dp[i] = max( dp[0], dp[1], ..., dp[i - 2] ) + nums[i]如何实现呢?

        思考这段方程的含义:这段方程是实现每次偷取第 i 个房间的时候选取前 i-2 个房间中能够获取的最大价值,考虑利用大根堆的优先队列实现。

        因为每次都要选取前 i - 2 个中的最大值,而大根堆的堆顶元素又是整个堆的最大值,可以考虑在 i = 2时开始向优先队列中插入元素,这样就能保证每次取出堆顶元素就是前 i - 2 个值中的最大值。

代码实现
class Solution {
public:int rob(vector<int>& nums) {// 利用优先队列和动态规划完成 dp[i] = max(dp[0]...dp[i-2]) + nums[i]// dp[i]表示偷取以i结尾的房间的最大价值和int len = nums.size();priority_queue<int> pq;vector<int> dp(len, 0);dp[0] = nums[0];int maxValue = nums[0];for(int i = 1; i < len; i++){if(i >= 2){pq.push(dp[i-2]);}if(i == 1){dp[i] = max(nums[i-1], nums[i]);}else{dp[i] = pq.top() + nums[i];}maxValue = max(maxValue, dp[i]);}return maxValue;}
};

解法二

1. 定义dp数组含义;

        dp[i]表示偷取前 i 个房间能够获得的最大价值;

2. 根据dp含义列出状态转移方程;

        每个房间都有偷与不偷两种可能,那么在计算dp[i]的时候就会出现两种情况;
        ①偷:dp[i] = dp[i-2] + nums[i];//不能偷连续的两个房间
        ②不偷:dp[i] = dp[i-1];//如果不偷那么当前的最大价值就是dp[i-1]的最大价值。

3. 确定边界条件;

        ①如果只有一个房间,那么dp[0] = nums[0];
        ②如果只有两个房间,那么dp[1] = max(nums[0], nums[1]);

4.思考实现方式;

        这个相对于解法一就很好实现了,利用vector容器即可。

代码实现
class Solution {
public:int rob(vector<int>& nums) {// dp[i]表示偷取前i的房间的最大价值和int len = nums.size();vector<int> dp(len, 0);dp[0] = nums[0];for(int i = 1; i < len; i++){if(i == 1){dp[i] = max(nums[0], nums[1]);}else{dp[i] = max(dp[i-1], dp[i-2] + nums[i]);}}return dp[len-1];}
};

结果展示

解法一解法二

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

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

相关文章

Linux 静态库和动态库

不管是Linux还是Windows中的库文件其本质和工作模式都是相同的, 只不过在不同的平台上库对应的文件格式和文件后缀不同。程序中调用的库有两种 静态库和动态库&#xff0c;不管是哪种库文件本质是还是源文件&#xff0c;只不过是二进制格式只有计算机能够识别&#xff0c;作为一…

【Node-RED 4.0.2】4.0版本新增特性(官方版)

二、重要功能 *1.时间戳格式改进 过去&#xff0c;node-red 只提供了 最原始的 timestamp 的格式&#xff08;1970-01-01 ~ now&#xff09; 但是现在&#xff0c;额外增加了 2 种格式&#xff1a; ISO 8601 -A COMMON FORMAT&#xff08;YYYY-MM-DDTHH:mm:ss:sssZ&#xff…

思考如何学习一门编程语言?

一、什么是编程语言 编程语言是一种用于编写计算机程序的人工语言。通过编程语言&#xff0c;程序员可以向计算机发出指令&#xff0c;控制计算机执行各种任务和操作。编程语言由一组语法规则和语义规则组成&#xff0c;这些规则定义了如何编写代码以及代码的含义。 编程语言…

linux和mysql基础指令

Linux中nano和vim读可以打开记事文件。 ifdown ens33 ifup ens33 关闭&#xff0c;开启网络 rm -r lesson1 gcc -o code1 code1.c 编译c语言代码 ./code1 执行c语言代码 rm -r dir 删除文件夹 mysql> show databases-> ^C mysql> show databases; -------…

常见网络端口号

在网络工程领域&#xff0c;了解和掌握默认端口号是至关重要的。端口号是计算机网络中最基本的概念之 一&#xff0c;用于标识特定的网络服务或应用程序。 1、什么是端口号&#xff1f; 端口号是计算机网络中的一种标识&#xff0c;用于区分不同的网络服务和应用程序。每个端…

【C++进阶学习】第五弹——二叉搜索树——二叉树进阶及set和map的铺垫

二叉树1&#xff1a;深入理解数据结构第一弹——二叉树&#xff08;1&#xff09;——堆-CSDN博客 二叉树2&#xff1a;深入理解数据结构第三弹——二叉树&#xff08;3&#xff09;——二叉树的基本结构与操作-CSDN博客 二叉树3&#xff1a;深入理解数据结构第三弹——二叉树…

想要打造超高性能的接口API?试试这12条小技巧。

1. 并行处理 简要说明 举个例子&#xff1a;在价格查询链路中&#xff0c;我们需要获取多种独立的价格配置项信息&#xff0c;如基础价、折扣价、商户活动价、平台活动价等等。 CompletableFuture 是银弹吗&#xff1f; 使用 CompletableFuture 的确能够帮助我们解决许多独…

走进IT的世界

引言 随着高考的结束&#xff0c;对于即将踏入IT&#xff08;信息技术&#xff09;领域的新生而言&#xff0c;这个假期不仅是放松身心的时间&#xff0c;更是提前规划、深化专业知识、为大学生活奠定坚实基础的宝贵机会。以下是一份详尽的高考假期预习与规划指南&#xff0c;…

Android自动化测试实践:uiautomator2 核心功能与应用指南

Android自动化测试实践&#xff1a;uiautomator2 核心功能与应用指南 uiautomator2 是一个用于Android应用的自动化测试Python库&#xff0c;支持多设备并行测试操作。它提供了丰富的API来模拟用户对App的各种操作&#xff0c;如安装、卸载、启动、停止以及清除应用数据等。此外…

30个!2024重大科学问题、工程技术难题和产业技术问题发布

【SciencePub学术】中国科协自2018年开始&#xff0c;组织开展重大科技问题难题征集发布活动&#xff0c;引导广大科技工作者紧跟世界科技发展大势&#xff0c;聚焦国家重大需求&#xff0c;开展原创性、引领性研究&#xff0c;不断夯实高质量发展的科技支撑。 自2024年征集活动…

飞书文档转markdown 超级快捷方法。

直接使用那个github的高赞官方的工具转换&#xff0c;需要设置什么小应用那种东西&#xff0c;还要审批&#xff0c;社恐人表示怕了怕了。而且文档我分享出去&#xff0c;是有权限的&#xff0c;反正无论如何生成不了 我的方法是 直接全选&#xff0c;然后粘贴进Arya - 在线 …

C#的五大设计原则-solid原则

什么是C#的五大设计原则&#xff0c;我们用人话来解释一下&#xff0c;希望小伙伴们能学会&#xff1a; 好的&#xff0c;让我们以一种幽默的方式来解释C#的五大设计原则&#xff08;SOLID&#xff09;&#xff1a; 单一职责原则&#xff08;Single Responsibility Principle…

PCL 渐进形态过滤器实现地面分割

点云地面分割 一、代码实现二、结果示例🙋 概述 渐进形态过滤器:采用先腐蚀后膨胀的运算过程,可以有效滤除场景中的建筑物、植被、车辆、行人以及交通附属设施,保留道路路面及路缘石点云。 一、代码实现 #include <iostream> #include <pcl/io/pcd_io.h> #in…

【LeetCode】976. 三角形的最大周长

1. 题目 2. 分析 需要分析好再动手编程。 如果要构成三角形的最大周长&#xff0c;那么就需要尽可能用最长的边构建。所以可以先对数组排个序&#xff0c;然后基于排序得到的结果从大往小的逐个检查长度为3的窗口&#xff0c;判断该窗口的值是否满足三角形的构成条件&#x…

鸿蒙开发Ability Kit(程序访问控制):【安全控件概述】

安全控件概述 安全控件是系统提供的一组系统实现的ArkUI组件&#xff0c;应用集成这类组件就可以实现在用户点击后自动授权&#xff0c;而无需弹窗授权。它们可以作为一种“特殊的按钮”融入应用页面&#xff0c;实现用户点击即许可的设计思路。 相较于动态申请权限的方式&am…

构造,析构,拷贝【类和对象(中)】

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;LiUEEEEE                        …

Excel_VBA编程

在Excel中&#xff0c;VBA&#xff08;Visual Basic for Applications&#xff09;是一种强大的工具&#xff0c;可以用来自动化各种任务。下面介绍一些常用的VBA函数和程序结构&#xff1a; 常用函数 MsgBox&#xff1a;用于显示消息框。 MsgBox "Hello, World!"In…

【python全栈系列】day07-python数据类型-集合

Python中的集合&#xff08;Set&#xff09;是一个无序的、不包含重复元素的数据结构。它主要用于数学上的集合操作&#xff0c;如并集、交集、差集和对称差集等。集合的基本用途包括去重和关系测试。 1、集合的特性 无序性&#xff1a;集合中的元素是无序的&#xff0c;这意…

gin-vue -admin 初始化安装后 进入 后台首页报错

报错原因&#xff1a; 因为 我是使用的phpstudy 小皮的数据库 默认的是MySam 的引擎 mysql 引擎需要是 innoDB 解决办法 &#xff1a; 在linux 的环境下 配置一个数据库 &#xff0c; 我是用的是vmware 虚拟机

深入理解分布式搜索引擎 ElasticSearch,并能基于 ELK+Kafka 搭建分布式⽇志收集系统

Elasticsearch是一个基于Lucene的分布式、多租户能力的全文搜索引擎。它提供了RESTful web接口和分布式多用户能力的全文搜索引擎&#xff0c;基于Apache许可证发行。以下是对Elasticsearch的深入理解以及如何基于ELK&#xff08;Elasticsearch、Logstash、Kibana&#xff09;加…