当前位置: 首页 > news >正文

解锁动态规划的奥秘:从零到精通的创新思维解析(6)

解锁动态规划的奥秘:从零到精通的创新思维解析(6)

前言:

在动态规划的众多问题中,多状态DP问题是一个非常重要的类别。它的难点在于如何设计合适的状态表示和转移方程,从而高效地解决问题。

多状态DP的核心思想在于:针对问题的不同属性或限制条件,将状态表示扩展为多个维度,使得状态可以更加精确地描述问题的子结构。这种方法既可以帮助我们更好地分解问题,又能够在求解过程中保留更多的信息,从而为最终的结果提供完整的支持。

在实际应用中,多状态DP常用于解决路径规划、背包问题、字符串编辑、博弈问题等场景。例如,在路径规划问题中,我们可以通过增加状态的维度来描述位置、步数以及路径的某些限制条件;在资源分配问题中,我们可以通过扩展状态来考虑当前的资源利用率和历史决策。

本篇内容将聚焦于多状态DP问题的基本原理和解决方法,结合典型实例,逐步介绍从状态定义、转移方程设计到代码实现的完整过程。希望通过这一系列讲解,读者能够对多状态DP的理论和实践有更深入的理解,掌握其在解决实际问题时的技巧与方法。

今天小编就要开启动态规划的多状态dp问题的讲解了,希望我讲完几篇文章后,对屏幕后的你会有一定程度的帮助,那么废话不多说,开启今天的做题之旅。

文章目录

  • 解锁动态规划的奥秘:从零到精通的创新思维解析(6)
    • 1.按摩师
      • 1.1.题目来源
      • 1.2.题目分析
      • 1.3.思路讲解
        • 1.状态表示
        • 2.状态转换方程
        • 3.初始化
        • 4.填表顺序
        • 5.返回值
      • 1.4.代码讲解
      • 1.5.完整代码展示
    • 2.删除并获得点数
      • 2.1.题目来源
      • 2.2.题目解析
      • 2.3.思路分析
        • 1.状态表示
        • 2.状态转换方程
        • 3.初始化
        • 4.填表顺序
        • 5.返回值
      • 2.4.代码讲解
      • 2.5.完整代码展示
    • 3.总结

1.按摩师

1.1.题目来源

这个题目和之前的题一样来自于力扣,下面小编给出本题的链接:面试题 17.16. 按摩师 - 力扣(LeetCode)外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1.2.题目分析

本题也是比较容易读懂的,虽然题干有点长,但是简单的概括下,其实就是一个按摩师在一天可以有两种选择,分别是选择接受预约和不接受预约,如果接受预约的话,那么后一天就不可以在预约了,因为连续两天是不可以去预约的,此时我们需要在一个数列中挑选预约时间,此时我们需要找到预约时间最长的集合,这便是这个题目的大体,下面小编进入题目的思路讲解。

1.3.思路讲解

对于动态规划的题目,我们需要先设置好一个dp表,之后我们就要五步走来分析问题了。

1.状态表示

对于本题的状态表示,我们还是靠经验 + 题目分析来完成这道题目,此时我们根据题意,可以知道此时的dp表有这两种意思,分别是接受预约和接受不预约,此时如果我们光靠一个一维的dp表,那还是远远不够的,所以本题就需要用到两个dp表来解决问题,这便是本节主要讲述的内容——多状态的dp问题,此时我们需要用到两个表,小编分别命名为f和g(高中的f(x) 和 g(x)函数演变而来),当然,虽然分为了两个表,但是我们的分析方法还是一样的,无非就是以i位置为结尾或者开头进行分析问题,此时我们让f[i]代表到达i位置时,接受此预约;g[i]表示达到此位置,不接受此预约;此时我们用了两个表分别表示了此时的状态,下面我们就可以写本题目的状态转换方程。

2.状态转换方程

我们可以先求f表的状态转换方程,此时我们知道了此时f表代表了什么,所以此时我们知道此时的i位置已经接受了预约,此时我们就可以判定i-1位置肯定是不会预约的(相邻两个位置不能预约),所以此时我们就可以表示出f[i]。

f[i] = g[i - 1] + nums[i];

之后我们在判断此时的g[i],相比于f[i],g[i]就复杂了一丢丢,此时我们可以把i-1分为两种情况,分别是前一天预约了和前一天没预约,因为此时i位置代表着不预约,这就不好说明它的前一天到底是预约了还是没有预约,所以此时我们需要判断一下选手,判断的条件也是很简单,此时我们仅需判断这两个谁最大就可以了,所以此时我们用max函数便可以表示出此时的方程。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

g[i] = max(f[i - 1],g[i - 1]);
3.初始化

此时因为初始化比较简单,所以此时我们无须在添加虚拟节点了,因为两个表都是第一个位置越界,所以此时我们先表示它俩就好了,其中的f[i]代表到达i位置的时候,接受预约,所以此时的f[0]自然就是nums[0](数组第一个元素);同理,此时的g[0]我们也可以表示为0(因为当前位置不选),此时我们的初始化工作便结束了。

4.填表顺序

从左到右,两个表一起填。

5.返回值

返回两个表最后一个位置中最大的那个。

1.4.代码讲解

此时我们需要先创建两个表,分别是f表和g表,此时对两个初始位置进行初始化处理。当然,此时有个特殊情况我们要讨论,此时如果数组没有元素,那么此时我们直接返回0就好,存在一个元素就直接返回第一个位置元素即可。

int n = nums.size();
//先判断特殊情况,放置越界
if(n == 0) return 0;
if(n == 1) return nums[0];
vector<int> f(n);  //选择
vector<int> g(n); //不选择
f[0] = nums[0];
g[0] = 0;

之后我们就根据状态转换方程进行循环填表即可,此时我们需要填两个表。之后返回两个表中最大的元素即可。

for(int i = 1 ; i < n ; i++){f[i] = g[i-1] + nums[i];g[i] = max(g[i-1],f[i-1]);}
return max(f[n-1],g[n-1]);

1.5.完整代码展示

class Solution {
public:int massage(vector<int>& nums) {int n = nums.size();//先判断特殊情况,放置越界if(n == 0) return 0;if(n == 1) return nums[0];vector<int> f(n);  //选择vector<int> g(n); //不选择f[0] = nums[0];g[0] = 0;for(int i = 1 ; i < n ; i++){f[i] = g[i-1] + nums[i];g[i] = max(g[i-1],f[i-1]);}return max(f[n-1],g[n-1]);}
};

2.删除并获得点数

2.1.题目来源

本题同样来自于力扣,下面小编给出链接:740. 删除并获得点数 - 力扣(LeetCode)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.2.题目解析

此时我们通过对题目的解读,可以很容易了解题目想告诉我们的东西:此时给定我们一个整数数组,此时我们可以选择其中的一个数,删除并获取它在数组中的所有值,只不过每次我们删完以后,还要直接删取它的相邻元素(可以理解为相邻元素不可以选取),就拿例1为例,此时我们可以选择删去4并获取它的点数,只不过此时我们要删掉3和5,此时数组中有3,所以我们要把3删掉,之后在选择2以后,此时我们就获得了此数组的最大点数,那就是4 + 2 == 6,这便是本题目想传递给我们的意思,下面进入思路分析部分。

2.3.思路分析

对于本题,我们可以先做一步预处理,因为此时如果我们一昧的去找点数删除点数,这个题目的难度系数会骤增,所以为了减轻难度,此时我们可以选择在开辟一个数组,这个数组的功能就是为了统计数组里面某个数所有的点数,简单来说,就是下标是数本身,里面存储的内容是在原数组该数所有和相加,类似哈希表,此时可以对这个新的数组来一次按摩师问题,这样本题目就解决完了,所以大多数小伙伴都知晓了本题目的核心就是预处理。

在预处理结束以后,此时我们可以在创建两个表,一个f表,一个g表,之后我们就可以根据动态规划的五步走来解决问题了。

1.状态表示

此时我们依靠经验 + 题目分析来解决本题目,此时我们可以以某个位置为结尾来分析问题;此时的f[i]表示到达i位置的时候,选取该位置的点数;g[i]表示当到达i位置的时候,不选择该点数,之后我们就可以进入方程的书写了。

2.状态转换方程

此时我们先分析f表,此时的f表代表着到达i位置时,选择该位置元素,所以我们可以推断出它之前的位置是不选取点数的,因为相邻点数不可以被选取,所以此时的f[i]可以表示为下:

f[i] = g[i - 1] + nums[i];

之后我们再来分析g表,此时的g表之前的状态可能会有两种,分别是之前选了或者是之前没选,此时我们选择其中的最大值作为该位置的值即可。

g[i] = max(f[i - 1],g[i - 1]);
3.初始化

因为此时我们新开辟的数组下标对应着点数,所以此时0位置的数据自然为0,因为不管有几个0,加起来还是0,所以此时的f表和g表第一个位置均为0即可(我们在创建的时候就默认为0了)。

4.填表顺序

从左到右,两表一起填写。

5.返回值

此时我们返回最后一个位置两表的最大值即可。

2.4.代码讲解

此时我们先要进行预处理操作,此时为了方便,我们直接用给定的数组的最大值作为新数组的大小,这样的话在之后的例子中就不会出现数组大小不够的情况了,之后我们让新数组下标对应着的值相加即可,然后创立两个新的表,分别是f表和g表。

int N = 10001;
vector<int> s(N);
for(auto e: nums) s[e] += e;  //此时右边的数组表示一个下标对应一个数有多少的数组
vector<int> f(N);
vector<int> g(N);

之后我们循环填入数据即可,此时这个步骤就不详讲了。填完后,返回两表最后一个位置的最大值即可。

for(int i = 1 ; i < N ; i++){f[i] = g[i - 1] + s[i];g[i] = max(g[i - 1],f[i - 1]);}
return max(f[N - 1],g[N - 1]);

2.5.完整代码展示

class Solution {
public:int deleteAndEarn(vector<int>& nums) {int N = 10001;vector<int> s(N);for(auto e: nums) s[e] += e;  //此时右边的数组表示一个下标对应一个数有多少的数组vector<int> f(N);vector<int> g(N);for(int i = 1 ; i < N ; i++){f[i] = g[i - 1] + s[i];g[i] = max(g[i - 1],f[i - 1]);}return max(f[N - 1],g[N - 1]);}
};

3.总结

本题目到这里也就完全结束了,今天是小编第一次讲述多状态dp问题,所以有些地方难免会出错,希望读者见谅,有错误可以在评论区指出,我会定时看评论,最近小编在期末备战,我越发觉的自己越到关键玩心越大,今日我又玩到了很晚,匆匆的结束本篇文章,希望以后的我看到这句话引以为戒,一起做题的时光总是很短暂,那么各位大佬们,我们下一篇文章见啦!
在这里插入图片描述

相关文章:

解锁动态规划的奥秘:从零到精通的创新思维解析(6)

解锁动态规划的奥秘&#xff1a;从零到精通的创新思维解析&#xff08;6&#xff09; 前言&#xff1a; 在动态规划的众多问题中&#xff0c;多状态DP问题是一个非常重要的类别。它的难点在于如何设计合适的状态表示和转移方程&#xff0c;从而高效地解决问题。 多状态DP的核…...

Qwen2.5 3B、7B、14B在文本按照规范进行标准化改写任务上的表现

任务介绍&#xff1a;军事杂志方向资料标准化改写任务 1. 任务目标 本任务的目标是对军事杂志领域的非标准化资料进行改写&#xff0c;确保其符合军事文献的写作规范和标准格式。通过改写&#xff0c;保留原文的核心内容和信息&#xff0c;同时提升语言的准确性、简洁性和专业…...

Oracle报错ORA-01078、LRM-00109

虚拟机异常关机后&#xff0c;rac数据库备机无法启动数据库&#xff0c;报错如下 解决方法&#xff1a; 找到如下路径文件 执行&#xff1a; cp init.ora.016202516818 /u01/app/oracle/product/19.3.0/db/dbs/ mv init.ora.016202516818 initplm2.ora 再次进入命令行sqlpl…...

免费为企业IT规划WSUS:Windows Server 更新服务 (WSUS) 之快速入门教程(一)

哈喽大家好&#xff0c;欢迎来到虚拟化时代君&#xff08;XNHCYL&#xff09;&#xff0c;收不到通知请将我点击星标&#xff01;“ 大家好&#xff0c;我是虚拟化时代君&#xff0c;一位潜心于互联网的技术宅男。这里每天为你分享各种你感兴趣的技术、教程、软件、资源、福利…...

Titans 架构中的记忆整合:Memory as a Context;Gated Memory;Memory as a Layer

Titans 架构中的记忆整合 Titans 架构中的记忆整合 Memory as a Context(MAC)变体:在处理长序列数据时,将序列分段,对于当前段 S ( t ) S^{(t)}...

无缝过渡:将 Ansys 子结构模型转换为 Nastran

了解如何将 Ansys 子结构模型无缝转换为 Nastran&#xff0c;以满足有效载荷动态模型要求 Ansys 子结构模型的优势 Ansys 子结构模型为从事大型装配体结构分析和仿真的工程师和分析师提供了多项优势。 这些模型通过将复杂结构划分为更小、更易于管理的子结构&#xff0c;可以…...

小哆啦的跳跃挑战:能否突破迷宫的极限?

小哆啦开始力扣每日一题的第六天 https://leetcode.cn/problems/jump-game/description/ 小哆啦的跳跃挑战&#xff1a;能否突破迷宫的极限&#xff1f; 第一阶段&#xff1a;小哆啦的初次尝试 —— 盲目跳跃 小哆啦刚进入跳跃之城&#xff0c;他决定采用一种非常直接的方法来…...

KubeSphere部署安装,接入KubeKey安装的k8s集群

KubeSphere安装接入KubeKey安装的k8s集群 文章目录 KubeSphere安装接入KubeKey安装的k8s集群 一.NFS安装配置1.服务器安装NFS服务2.下载并部署 NFS Subdir External Provisioner1).下载部署文件2).创建 NameSpace3).创建 RBAC 资源4).配置 deployment.yaml5).部署 Storage Clas…...

Object常用的方法及开发中的使用场景

在前端开发中&#xff0c;Object 对象提供了许多常用的方法&#xff0c;这些方法帮助我们操作对象的属性和结构。以下是常用的 Object 方法及其功能简要说明&#xff1a; 对象常用的方法 1. 创建对象 Object.create(proto[, propertiesObject]) 创建一个具有指定原型对象和属性…...

SQL2000在win10上安装的方法

安装前最好先关闭防火墙和一些杀毒软件&#xff0c;因为这些软件在安装过程中可能会碰到注册表等一下杀毒软件比较敏感的地带&#xff0c;如果违反杀毒软件的规则会被当做病毒强行终止删除 首相找到C盘下window文件中的sysWOW64文件 鼠标右键&#xff0c;点击属性、安全、高级 …...

Windows图形界面(GUI)-QT-C/C++ - QT 对话窗口

公开视频 -> 链接点击跳转公开课程博客首页 -> ​​​链接点击跳转博客主页 目录 模态对话框 非模态对话框 文件对话框 基本概念 静态函数 常见属性 颜色对话框 基本概念 静态函数 常见属性 字体对话框 基本概念 静态函数 常见属性 输入对话框 基本概念 …...

Java语言的数据结构

Java语言中的数据结构 引言 在计算机科学中&#xff0c;数据结构是指一种特定的方式来组织和存储数据&#xff0c;以便能够高效地进行访问和修改。Java作为一种广泛使用的编程语言&#xff0c;其内置的数据结构和集合框架为程序员提供了便利的工具来管理数据。本文将深入探讨…...

【12】Word:张老师学术论文❗

目录 题目 ​NO2 NO3 NO4 NO5 NO6 NO7.8 题目 NO2 布局→页面设置→纸张&#xff1a;A4→页边距&#xff1a;上下左右边距→文档网格&#xff1a;只指定行网格→版式&#xff1a;页眉和页脚&#xff1a;页脚距边界&#xff1a;1.4cm居中设置论文页码&#xff1a;插入…...

大疆最新款无人机发布,可照亮百米之外目标

近日&#xff0c;DJI 大疆发布全新小型智能多光旗舰 DJI Matrice 4 系列&#xff0c;包含 Matrice 4T 和 Matrice 4E 两款机型。DJI Matrice 4E 价格为27888 元起&#xff0c;DJI Matrice 4T价格为38888元起。 图片来源&#xff1a;大疆官网 DJI Matrice 4E DJI Matrice 4T D…...

《小迪安全》学习笔记05

目录 读取&#xff1a; 写入&#xff1a; &#xff08;其中的读取和写入时我认为比较重要的&#xff0c;所以单独做成了目录&#xff0c;这里的读取和写入是指在进行sql注入的时候与本地文件进行的交互&#xff09; 好久没发博客了。。。从这篇开始的小迪安全学习笔记就开始…...

56_多级缓存实现

1.查询Tomcat 拿到商品id后,本应去缓存中查询商品信息,不过目前我们还未建立Nginx、Redis缓存。因此,这里我们先根据商品id去Tomcat查询商品信息。此时商品查询功能的架构如下图所示。 需要注意的是,我们的OpenResty是在虚拟机,Tomcat是在macOS系统(或Windows系统)上,…...

每日进步一点点(网安)

今日练习题目是PHP反序列化&#xff0c;也学习一下说明是序列化和反序列化 1.PHP序列化 序列化是指将数据结构或对象转换为可传输或可储存的格式的过程。这通常需要将数据转换为字节流或者其他编码格式&#xff0c;以便在不同系统和应用程序之间进行传输或存储 在PHP中&…...

宝塔php7.4安装报错,无法安装,php8以上可以安装,以下的不行,gd库什么的都正常

宝塔的依赖问题导致的问题&#xff0c;最后手动挂载后才解决。。。废了三天三夜终于搞好了。。。。无语&#xff5e; 建议&#xff1a;不要一直升级宝塔版本&#xff0c;升级前备份或者开服务商的实例镜像&#xff0c;方便恢复&#xff0c;不然&#xff0c;可就GG了&#xff5…...

SDL2:PC端编译使用

SDL2&#xff1a;PC端编译使用 1. SDL2&#xff1a;PC端编译使用1.1 安装必要的依赖1.2 下载编译SDL21.3 SDL2使用示例&#xff1a;Audio1.4 运行示例程序 1. SDL2&#xff1a;PC端编译使用 1.1 安装必要的依赖 首先&#xff0c;确保安装了编译SDL2所需的依赖库&#xff1a; …...

Windows 蓝牙驱动开发-蓝牙设备栈

蓝牙设备栈 蓝牙驱动程序堆栈包含 Microsoft 为蓝牙协议提供支持的核心部分。 有了这个堆栈&#xff0c;已启用蓝牙的设备可以彼此定位并建立连接。 在此类连接中&#xff0c;设备可以通过各种应用程序交换数据并彼此交互。 下图显示了蓝牙驱动程序堆栈中的模块&#xff0c;以…...

docker一张图理解

1、push 将本地的镜像上传到镜像仓库,要先登陆到镜像仓库。参数说明&#xff1a; –disable-content-trust : 忽略镜像的校验,默认开启 # 上传本地镜像myapache:v1到镜像仓库中。 docker push myapache:v1 1.2、search 从Docker Hub查找镜像。参数说明&#xff1a; –…...

RocketMQ、Kafka、RabbitMQ,如何选型?

如何根据应用场景选择合适的消息中间件? 分布式、微服务、高并发架构中&#xff0c;消息队列&#xff08;Message Queue&#xff0c;简称MQ&#xff09;扮演着至关重要的角色。 消息队列用于实现系统间的异步通信、解耦、削峰填谷等功能。 目前常见的MQ实现包括RabbitMQ、Rock…...

RabbitMQ故障全解析:消费、消息及日常报错处理与集群修复

文章目录 前言&#xff1a;1 消费慢2 消息丢失3 消息重复消费4 日常报错及解决4.1 报错“error in config file “/etc/rabbitmq/rabbitmq.config” (none): no ending found”4.2 生产者发送消息报错4.3 浏览器打开IP地址&#xff0c;无法访问 RabbitMQ&#xff08;白屏没有结…...

无公网IP 实现外网访问本地 Docker 部署 Navidrome

Navidrome 是一款可以在 macOS、Linux、Windows以及 Docker 等平台上运行的跨平台开源音乐服务器应用&#xff0c;它支持传输常见的 MP3、FLAC、WAV等音频格式。允许用户通过 Web 界面或 API 进行音乐库的管理和访问。本文就介绍如何快速在 Linux 系统使用 Docker 进行本地部署…...

pnpm add 和 pnpm install 的区别?

文章目录 1. pnpm add2. pnpm install3. 总结应用场景示例 在使用 pnpm 管理项目依赖时&#xff0c; pnpm add 和 pnpm install 是两个常用的命令&#xff0c;但它们的功能和使用场景有所不同。以下是详细的解释&#xff1a; 1. pnpm add 功能&#xff1a;用于向项目的 pack…...

Linux:文件描述符fd、系统调用open

目录 一、文件基础认识 二、C语言操作文件的接口 1.> 和 >> 2.理解“当前路径” 三、相关系统调用 1.open 2.文件描述符 3.一切皆文件 4.再次理解重定向 一、文件基础认识 文件 内容 属性。换句话说&#xff0c;如果在电脑上新建了一个空白文档&#xff0…...

CPU负载与CPU使用率之区别

在日常的性能测试与系统监控中&#xff0c;CPU负载和CPU使用率是两个常见的指标&#xff0c;它们经常被提及&#xff0c;但也经常被混淆。本文将为你深入解析两者的区别&#xff0c;以及它们各自的意义和应用场景&#xff0c;让你更清楚地掌握这些关键性能指标。 存储、内存和 …...

C++实现设计模式---外观模式 (Facade)

外观模式 (Facade) 外观模式 是一种结构型设计模式&#xff0c;为子系统中的一组接口提供一个一致的界面。外观模式定义了一个更高层次的接口&#xff0c;使得子系统更容易使用。 意图 简化复杂子系统的接口。为客户端提供一个统一的入口&#xff0c;屏蔽子系统的内部细节。 …...

仿射密码实验——Python实现(完整解析版)

文章目录 前言实验内容实验操作步骤1.编写主程序2.编写加密模块3.编写解密模块4.编写文件加解密模块 实验结果实验心得实验源码scirpt.pyusefile.py 前言 实验目的 1&#xff09;初步了解古典密码 2&#xff09;掌握仿射密码的实现 实验方法 根据下图仿射密码&#xff08;变换…...

【Qt 常用控件】按钮类(QPushButton、QRadioButton、QCheckBox)

按钮控件继承自抽象类QAbstractButton。 抽象类不允许实例化对象&#xff0c;内部定义纯虚函数。只能通过子类继承&#xff0c;重写纯虚函数的方式使用。 1. QPushButton 1.1 QAbstractButton中和QPushButton相关的属性 text按钮显示文本icon按钮图标iconSize按钮图标尺寸s…...