● 198.打家劫舍 ● 213.打家劫舍II ● 337.打家劫舍III

● 198.打家劫舍
动规五部曲。

1、dp[j]含义。前j个房屋偷到的金额之和最大是dp[j]。

2、递推公式。递推公式要得出dp[i],就是要确定第i个房屋是否打劫,那么也跟之前的背包问题一样,放与不放,对应的是两种结果,我们只需要取这两种结果的最大值就行,而不需要用if-else语句来判断放和不放两种情况。

第i个房屋不被打劫,肯定前一个房屋要被打劫,所以此时dp[i]=dp[i-1]。

第i个房屋被打劫,肯定前一个房屋不能被打劫,所以dp[i]=dp[i-2]+nums[i]。因为i-1个房屋不考虑。

因此dp[i]是这两个数的最大值:dp[i]=max(dp[i-1], dp[i-2]+nums[i])

3、初始化。初始化要根据dp[j]含义来,上面递推公式涉及到前两个房屋,所以下标为0和 为1的房屋都要初始化。前1个房屋偷到的金额之和是nums[0],第2个房屋偷到的金额之和是max(nums[0],nums[1])。

或者说:只有1个房屋的话,就偷这一家,有2个房屋的话,偷其中金额大的那一家。

4、遍历顺序。到达第i个房屋,dp[i]需要根据前两个房屋的dp来,所以是正序遍历。

5、打印dp数组。

代码如下:
class Solution {
public:int rob(vector<int>& nums) {if(nums.size()==1)return nums[0];vector<int> dp(nums.size(),0);dp[0]=nums[0];dp[1]=max(nums[0],nums[1]);for(int i=2;i<nums.size();++i){dp[i]=max(dp[i-2]+nums[i],dp[i-1]);}return dp.back();}
};

● 213.打家劫舍II
和上一题的区别,主要在于首元素、尾元素要不要考虑。上一题就是首尾元素以及中间的都考虑了,这道题的话首元素或者尾元素最多只有一个被选择,所以有下面三种情况:


情况1。首尾不选择,只考虑中间的。

情况2。
情况3。

是把这几种情况的最大金额分别算出来然后取最大值。


又因为情况2和情况3共有的部分包含了情况3,所以把情况2、情况3的最大金额分别算出来然后取最大值。

算最大值的过程就是和上一题一样,所以用两次上一题的过程,那么封装成一个函数。

代码如下。

class Solution {
public:int subrob(vector<int>& nums,int a,int b){//只考虑[a,b]范围内的vector<int> dp(nums.size(),0);dp[a]=nums[a];  dp[a+1]=max(nums[a],nums[a+1]);for(int i=a+2;i<=b;++i){dp[i]=max(dp[i-2]+nums[i],dp[i-1]);}return dp[b];}int rob(vector<int>& nums) { int n=nums.size();if(n==1)return nums[0];if(n==2)return max(nums[0],nums[1]);int rob1=subrob(nums,0,nums.size()-2);  //不考虑尾int rob2=subrob(nums,1,nums.size()-1);  //不考虑首return max(rob1,rob2);}
};
● 337.打家劫舍III

树形dp的入门题目。

要讨论某节点劫还是不劫,根据每个节点,我们只能知道它的两个孩子。如果这个节点选了,那么它的两个孩子就不能被打劫,这的两个孩子其实与上两道题的前一个房屋对应,所以只能后序遍历节点来解决,因为先要处理左右孩子,再根据孩子处理自己,左右中。

自己想不到的:不像之前的线性dp一样:一个dp数组,包含给定个数的元素。这里是遍历到一个节点了,就设置一个dp数组,这个数组里面2个元素:dp[0]是不选自己的最大值,dp[1]是选自己的最大值。主函数里面得到根节点的dp数组,然后返回根节点的dp[0]和dp[1]中的一个最大值就行,可见dp[0]和dp[1]是和前面dp[i]的max取值里面两个表达式含义相同。所以在递归体里面,我们要根据节点i左、右孩子的dp数组,得到i自己的的dp数组,一路向上,最终得到root的dp数组。

那么还是按递归的框架来,五部曲体现在递归体之中。

递归的返回类型应该是该节点的dp数组,告诉自己的父节点:不选自己打劫到的最大值和选择自己打劫到的最大值。父节点就根据左、右孩子的dp数组,来确定自己的dp数组。

就回到动规的递推公式,假设左孩子返回的dp数组是dpLeft,右孩子返回的dp数组是dpRight。首先看dp[1],选择了自己,那么左右孩子肯定不选,所以dp[1]应该等于不选左孩子打劫到的最大值dpLeft[0]加上不选右孩子打劫到的最大值dpRight[0],再加上自己的数,即:

dp[1]=dpLeft[0]+dpRight[0]+root->val;

再看dp[0],自己不选择,孩子选不选都可以。刚开始觉得孩子得左右都选,才是最大,但是这只是局部的最大,而不是全局。比如下面的结构:

正确结果应该是4、3,那么节点1的孩子2就没有选择。

既然左、右孩子选不选都可以,那我们应该选择左、右孩子选和不选两种情况的最大值然后加起来。所以dp[0]应该等于左孩子dp[0]和dp[1]的最大值,再加上右孩子dp[0]和dp[1]的最大值。

        dp[0]=max(dpLeft[1],dpLeft[0])+max(dpRight[0],dpRight[1]);//没选自己,左右孩子选与不选都可以

代码如下:

/* Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:vector<int> digui(TreeNode* root){if(!root)return vector<int>{0,0};//空节点vector<int> dp(2,0);//dp[0];dp[1]vector<int> dpLeft=digui(root->left);vector<int> dpRight=digui(root->right);dp[0]=max(max(dpLeft[1]+dpRight[1],dpLeft[0]+dpRight[1]),max(dpLeft[1]+dpRight[0],dpLeft[0]+dpRight[0]));//没选自己,可能左右孩子全选,也可能不选dp[1]=dpLeft[0]+dpRight[0]+root->val;//选自己,孩子肯定不选return dp;} int rob(TreeNode* root) {vector<int> dp(2);dp=digui(root);return max(dp[0],dp[1]);}
};

打印dp数组。按照每个节点得到dp[0]、dp[1]的过程先推导一下。

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

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

相关文章

旺泓_光感WH3620_数字RGBW-IR色彩传感器

由工采网代理的WH3620是一种基于颜色的光到数字转换器;它集光电二极管、电流放大器、模拟电路和数字信号处理器于一体&#xff1b;提供红、绿、蓝、白和红外光传感&#xff1b;能调节屏幕或灯光白平衡&#xff1b;各通道同时并行输出&#xff0c;因此在白光LED、CWF、TL84、D65…

防患未然,OceanBase巡检工具应用实践——《OceanBase诊断系列》之五

1. OceanBase为什么要做巡检功能 尽管OceanBase拥有很好的MySQL兼容性&#xff0c;但在长期的生产环境中&#xff0c;部署不符合标准规范、硬件支持异常&#xff0c;或配置项错误等问题&#xff0c;这些短期不会出现的问题&#xff0c;仍会对数据库集群构成潜在的巨大风险。为…

脾胃论笔记

焦虑会导致脾胃受伤 焦虑等不良情绪也会导致脾胃受伤&#xff0c;我们称其为肝气不舒。肝气不舒会导致脾胃系统出问题&#xff0c;这叫肝木横逆克脾土&#xff0c;木克土&#xff0c;脾胃就容易受伤。 这样的情况在现代社会特别多。这跟古人就不一样&#xff0c;古人生活相对…

Python爬虫——Requests

目录 简介 基本使用​编辑 ​编辑 安装 一个类型和六个属性 请求类型 GET 代码示例 POST 代码示例 代理 古诗文网绕过验证码登录 总结 简介 Python的Requests库是一个用于发送HTTP请求的常用库。它提供了简单且人性化的API&#xff0c;使得发送HTTP请求变得非常容易。…

完美解决VMware中配置suse10虚拟机网络

一、注意&#xff01;&#xff01;&#xff01;配置suse10网络&#xff0c;需要在虚拟机关机状态下进行&#xff0c;否则会配置不成功&#xff1b; 二、配置与主机在同一网段(仅主机模式&#xff0c;网卡一)&#xff1b; 在suse系统关机状态下&#xff0c;Vmware中设置”虚拟网…

2024华为Android高级面试题及答案,android系统工程师面试

大厂offer是每个技术人的追求? 我觉得每一个程序员的梦想大概就是能够找一份大厂的 Offer&#xff0c;我觉得这很正常&#xff0c;这并不是我们的饭后谈资而是每个技术人的追求。像阿里、腾讯、美团、字节跳动、京东等等的技术氛围与技术规范度还是要明显优于一些创业型公司/…

0.8秒一张图40hx矿卡stable diffusion webui 高质极速出图组合(24.3.3)

新消息是。经过三个月的等待&#xff0c;SD Webui (automatic1111)终于推出了新版本1.8.0&#xff0c;本次版本最大的更新&#xff0c;可能就是pytorch更新到2.1.2, 不过还是晚了pytorch 2.2.2版。 不过这版的一些更新&#xff0c;在forget分支上早就实现了&#xff0c;所以。…

2核4G云服务器就服阿里云,这性能无敌了

阿里云2核4G服务器多少钱一年&#xff1f;2核4G配置1个月多少钱&#xff1f;2核4G服务器30元3个月、轻量应用服务器2核4G4M带宽165元一年、企业用户2核4G5M带宽199元一年。可以在阿里云CLUB中心查看 aliyun.club 当前最新2核4G服务器精准报价、优惠券和活动信息。 阿里云官方2…

一文了解74HCT14D的引脚图、符号、封装、数据手册及应用

74HCT14D 是一款采用硅栅 C2MOS 技术制造的高速 CMOS 施密特逆变器。它实现了类似于等效 LSTTL 的高速操作&#xff0c;同时保持 CMOS 的低功耗。该器件可用作电平转换器&#xff0c;用于将 TTL 或 NMOS 连接到高速 CMOS。 输入与 TTL、NMOS 和 CMOS 输出电压电平兼容。所有输入…

什么是工业级物联网智能网关?如何远程控制PLC?

在这个信息爆炸的时代&#xff0c;物联网技术已经逐渐渗透到我们生活的方方面面&#xff0c;而工业级物联网智能网关作为连接工业设备和云端的重要桥梁&#xff0c;更是引领着工业4.0时代的浪潮。那么&#xff0c;究竟什么是工业级物联网智能网关呢&#xff1f;今天&#xff0c…

Python网络请求高级篇:Requests库的深度运用

在Python网络请求中级篇中&#xff0c;我们了解了如何通过Requests库发送带参数的请求&#xff0c;处理Cookies&#xff0c;使用Session对象&#xff0c;以及设置请求头。在本文中&#xff0c;我们将进一步深入学习Requests库的高级功能&#xff0c;包括处理重定向&#xff0c;…

Codesys 位置式PID闭环控制系统(PID+PWM控制无刷电机)

有关Codesys位置式PID算法公式和源代码,请参考下面文章链接: 1、Codesys位置式PID https://rxxw-control.blog.csdn.net/article/details/131591254https://rxxw-control.blog.csdn.net/article/details/1315912542、博途PLC PWM输出控制 https://rxxw-control.blog.csdn.…

Flink基本原理 + WebUI说明 + 常见问题分析

Flink 概述 Flink 是一个用于进行大规模数据处理的开源框架&#xff0c;它提供了一个流式的数据处理 API&#xff0c;支持多种编程语言和运行时环境。Flink 的核心优点包括&#xff1a; 低延迟&#xff1a;Flink 可以在毫秒级的时间内处理数据&#xff0c;提供了低延迟的数据…

证件照制作繁琐?学会这三招轻松制作专业级证件照!

朋友们&#xff0c;您是否曾经为了办理各种证件、报名考试或者求职简历中的证件照而烦恼呢&#xff1f;是否希望能在家就能便捷高效地制作出符合规格的专业证件照&#xff1f;今天我将为大家推荐三款国内外备受好评的证件照处理工具&#xff0c;让您随时随地拥有完美证件照&…

【prompt四】Domain Prompt Learning for Efficiently Adapting CLIP to Unseen Domains

motivation 领域泛化(DG)是一个复杂的迁移学习问题,旨在学习未知领域的可泛化模型。最近的基础模型(FMs)对许多分布变化都具有鲁棒性,因此,应该从本质上提高DG的性能。在这项工作中,我们研究了采用视觉语言基础模型CLIP来解决图像分类中的DG问题的通用方法。虽然ERM使用标…

音视频开发之旅——音频基础概念、交叉编译原理和实践(LAME的交叉编译)(Android)

本文主要讲解的是音频基础概念、交叉编译原理和实践&#xff08;LAME的交叉编译&#xff09;&#xff0c;是基于Android平台&#xff0c;示例代码如下所示&#xff1a; AndroidAudioDemo 音频基础概念 在进行音频开发的之前&#xff0c;了解声学的基础还是很有必要的。 声音…

K线实战分析系列之二十二:圆形顶部和圆形底部形态

K线实战分析系列之二十二&#xff1a;圆形顶部和圆形底部形态 一、圆形顶部形态二、圆形顶部和圆形底部形态的总结 一、圆形顶部形态 市场多空一方被逐渐击退&#xff0c;跳空的缺口是一方突然发力&#xff0c;体现出一方对市场掌握了控制权 二、圆形顶部和圆形底部形态的总结…

IDEA切换JDK版本超详细步骤

&#x1f600; IDEA切换JDK版本详细教程&#xff0c;全网步骤最详细&#xff0c;实测可用。 文章目录 第一步、选择SDKs切换SDK版本&#xff1a;第二步、选择Modules切换Sources和Dependencies版本&#xff1a;第三步、选择Project切换SDK和Language Level版本&#xff1a;第四…

2024年冲刺年薪40w,java面试常问知识点

前言 刚刚过去的双十一&#xff0c;让“高性能”“高可用”“亿级”这3个词变成了技术热点词汇&#xff0c;也让很多人再次萌发成为「架构师」的想法。先问大家一个问题&#xff1a;你觉得把代码熟练、完成需求加上点勤奋&#xff0c;就能成为架构师么&#xff1f;如果你这么认…

MySQL:索引的优化方法

索引是帮助存储引擎快速获取数据的一种数据结构&#xff0c;形象的说就是索引是数据的目录。 索引创建的时机&#xff1a; 索引并不是越多越好的&#xff0c;虽然他再查询时会提高效率&#xff0c;但是保存索引和维护索引也需要一定的空间和时间成本的。 不创建索引&#xff1a…