在这里插入图片描述

算法相关知识点可以通过点击以下链接进行学习一起加油!
斐波那契数列模型路径问题

多状态问题通常涉及多个决策点和状态转换,解决起来复杂且计算量大。动态规划作为一种强大的算法工具,能够通过将问题分解为子问题并逐步求解,显著提升解决这类问题的效率。本文将探讨如何运用动态规划技术有效处理复杂的多状态问题,帮助读者理解其背后的原理,并展示如何设计高效的状态转移方程以优化问题求解过程。

请添加图片描述

Alt

🌈个人主页:是店小二呀
🌈C/C++专栏:C语言\ C++
🌈初/高阶数据结构专栏: 初阶数据结构\ 高阶数据结构
🌈Linux专栏: Linux
🌈算法专栏:算法
🌈Mysql专栏:Mysql

🌈你可知:无人扶我青云志 我自踏雪至山巅 请添加图片描述

文章目录

    • 面试题 17.16. 按摩师
    • 213. 打家劫舍 II
    • 740. 删除并获得点数
    • LCR 091. 粉刷房子
    • 309. 买卖股票的最佳时机含冷冻期
    • 714.买卖股票的最佳时机含手续费
    • 123. 买卖股票的最佳时机 III
    • 188. 买卖股票的最佳时机 IV

面试题 17.16. 按摩师

题目】:面试题 17.16. 按摩师

在这里插入图片描述

算法思路

在这里插入图片描述

通过题目分析,状态可以表示为选择到第 i 位置时的最长预约时长。进一步细化后,题目提供了两种状态:是否选择 nums[i],这会影响最终结果。为此,我们可以创建两个 DP 表,分别表示选择或不选择 nums[i] 的情况,并根据不同状态进行处理。

题目要求不能连续选择,因此我们需要根据状态的定义以及与前一个状态之间的关系,推导出状态转移方程。对于不选择 nums[i] 的情况,上一状态的选择与否都会影响当前的最长预约时长,这与具体的选择策略密切相关

解决问题的关键在于,通过在第 i 位置引入多种状态,利用动态规划(DP)来求解。结合题目需求,我们需要确保DP表之间的状态连续性,从而推导出合理的状态转移方程。

代码实现

class Solution {
public:int massage(vector<int>& nums) {int n = nums.size();if(n == 0) return 0;///1.为多状态创建dp表vector<int> f(n);vector<int> g(n);//2.初始化f[0] = nums[0];//3.填表for(int i = 1; i < n; i++){f[i] = g[i - 1] + nums[i];g[i] = max(f[i - 1], g[i - 1]);}//4.返回值return max(f[n - 1],g[n - 1]);}
};

213. 打家劫舍 II

题目】:213. 打家劫舍 II

在这里插入图片描述

算法思路

在这里插入图片描述

绘图分析是一种快速的问题分析方法。通过画图分析,我们可以根据第一个位置是否选择,分成两个部分。剩余部分的处理方式与“面试题 17.16. 按摩师”的解法类似,使用简单的多状态动态规划(DP)方法即可解决。

在解决问题的过程中,可以根据一些特殊条件将问题划分为子问题,从而使用相同的逻辑来处理这些子问题,这样有助于简化并有效解决其中可能存在的特殊情况。

代码实现

class Solution {
public:int rob(vector<int>& nums) {   int n = nums.size();int ret =max ( nums[0] + rob1(nums, 2, n - 2), rob1(nums,1, n - 1));return ret;}int rob1(vector<int>& nums, int left, int rigth){if(left > rigth) return 0;//1.创建db表int n = nums.size();vector<int> f(n);auto g = f;//2.初始化f[left] = nums[left];//3.填表for(int i = left + 1; i <= rigth; i++){f[i] = g[i - 1] + nums[i];g[i] = max(f[i - 1], g[i - 1]);}return max(f[rigth],g[rigth]);}
};

740. 删除并获得点数

题目】:740. 删除并获得点数

在这里插入图片描述

算法思路

在这里插入图片描述

有些题目可能需要预处理,才能更容易发现使用动态规划(DP)来解决问题。例如,在这道题中,直接从题目入手使用DP并不可取。我们需要删除 nums[i] - 1nums[i] + 1 这些元素,换句话说,要跳过这些无法相加的元素。

同时,题目要求获取最大值,通常在这种情况下,若需要快速查找元素,需要连续下标访问,哈希表是一个常见的选择。但在这里,我们只需要根据数组下标来查找元素,元素代表相加点数,数值为下标方便操作,因此可以用数组的下标值作为哈希表的替代,通过这种方式进行DP操作更加简便。

代码实现

class Solution {
public:int deleteAndEarn(vector<int>& nums) {//1.预处理const int N = 10001;int arr[N] = {0};for(auto x : nums) arr[x] += x;//2.创建dp表vector<int> f(N);auto g = f;//3.填表操作for(int i = 1; i < N; i++){f[i] = g[i - 1] + arr[i];g[i] = max(f[i - 1], g[i - 1]);}return max(f[N - 1], g[N - 1]);}
};

LCR 091. 粉刷房子

题目】:LCR 091. 粉刷房子

在这里插入图片描述

算法思路

在这里插入图片描述
在这里插入图片描述

属于很典型的简单多状态dp问题,在i位置时候,通过选择颜色,此时的最小花费。dp细分为三种颜色,在该i位置的最小花费,然后跟最近一次状态,写出状态转移方程。三个状态表示相互作用,相互呼应,最后判断最小就行了。这里建议搞个虚拟节点。

代码分析

我们可以搭建一个二维数组,其中每个元素代表一个分化的DP表,用来记录在第 i 位置选择某种颜色时的最小花费。

根据分析出的状态转移方程,可以通过另外两个DP表获取前两个状态的最小值,并加上当前颜色的花费,从而计算出当前状态的最小花费。可以将这两个二维数组视作叠加在一起,三个DP表根据状态转移方程共同处理问题,通过这种方式有效地求解最小花费。

感觉面向过程有点难,不如选择面向对象编程,对于这些问题的处理。

虚拟节点

虚拟节点需要保证后续填表正确性,那么可以图像结合状态转移方程,决定虚拟节点初始化数值。

代码实现

class Solution {
public:int minCost(vector<vector<int>>& costs) {int n = costs.size();//1.多状态 创建dp表vector<vector<int>> dp(n + 1,vector<int>(3));//2.初始化操作dp[0][0] = dp[0][1] = dp[0][2] = 0;for(int i = 1; i <= n; i++){dp[i][0] = min(dp[i - 1][1], dp[i - 1][2]) + costs[i - 1][0];dp[i][1] = min(dp[i - 1][0], dp[i - 1][2]) + costs[i - 1][1];dp[i][2] = min(dp[i - 1][1], dp[i - 1][0]) + costs[i - 1][2]; }return min(dp[n][1], min(dp[n][2], dp[n][0]));}
};

309. 买卖股票的最佳时机含冷冻期

题目】:309. 买卖股票的最佳时机含冷冻期

在这里插入图片描述

算法思路

在这里插入图片描述

结合上道题经验,遇到状态超过两种,可以使用0,1,2标识不同状态标识,dp[i] [0]、dp[i] [1]、dp[i] [2]表示i位置,巴拉巴拉状态。

常用手段是画出"状态机"分析状态之间转化,方便写出动态转移方程和初始化处理。这里选择以为i位置结束,所表示状态。根据状态机某个位置,结合最近一次位置结合题目分析,写出然后得到当前位置数值,从而得到状态转移方程。

代码实现

class Solution {
public:int maxProfit(vector<int>& prices) {int n = prices.size();//1.创建多状态dp表vector<vector<int>> dp(n, vector<int>(3));//2.初始化dp[0][0] = -prices[0];dp[0][1] = dp[0][2] = 0;//3.填表for(int i = 1; i < n; i++){dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]);dp[i][1] = max(dp[i - 1][1], dp[i - 1][2]);dp[i][2] = dp[i - 1][0] + prices[i];}return max(dp[n - 1][1], max(dp[n - 1][2], dp[n - 1][0]));}
};

714.买卖股票的最佳时机含手续费

题目】:714. 买卖股票的最佳时机含手续费

在这里插入图片描述

算法思路

在这里插入图片描述

首先,根据经验和题目要求,得出状态转移方程。然后选择合适的i位置进行状态分析,得到买入状态和可交易状态的表示。

接下来,可以通过关联最近一次的位置来确定状态转移方程,或者绘制状态机图,将所有状态转化过程进行分析。最后,初始化相关位置,通过状态转移方程确定初始位置,并在图中进行分析。

代码实现

class Solution {
public:int maxProfit(vector<int>& prices, int fee) {//1.创建dp表int n = prices.size();vector<int> f(n);auto g = f;//2.初始化f[0] = -prices[0];g[0] = 0;//3.填表操作for(int i = 1; i < n; i++){f[i] = max(f[i - 1], g[i - 1] - prices[i]);g[i] = max(g[i - 1], f[i - 1] + prices[i] - fee);}return g[n- 1];}
};

123. 买卖股票的最佳时机 III

题目】:123. 买卖股票的最佳时机 III

在这里插入图片描述

算法思路

在这里插入图片描述

在解决问题之前,我们需要结合题目和样例进行绘图模拟,直观地展示整个过程。在这里,'最多’的含义是指从0到最大范围,而并非一定要选择这么多。

在这里插入图片描述

首先,根据’经验 + 题目要求’得到初步的状态表示,并通过 i 位置进行分析。如果发现该状态表示不够充分,可以增加一个位置来表示’完成了多少次交易’。

接下来,绘制状态机并推导出状态转移方程。在处理状态转移方程时,需考虑所有细节。例如,题目中的状态转移方程可能会涉及越界问题,需在初始化过程中解决这个隐含问题。

特别需要注意的是,第一行位置的初始化应为[1, n - 1]并设置为无穷小,以避免不必要的干扰。此外,初始化某些位置时,要确保它们不会影响后续位置的正确计算,或者确保后续位置能够正确更新。

代码实现

class Solution {
public:const int INT = -0x3f3f3f3f;int maxProfit(vector<int>& prices) {//1.创建dp表int n = prices.size();vector<vector<int>> f(n, vector<int>(3,INT));auto g = f;//2.初始化f[0][0] = -prices[0];g[0][0] = 0;//3.填表操作for(int i = 1; i < n; i++){for(int j = 0; j < 3; j++){f[i][j] = max(f[i - 1][j], g[i - 1][j] - prices[i]);g[i][j] = j - 1 >= 0 ? max(g[i - 1][j], f[i - 1][j - 1] + prices[i]) : g[i - 1][j];}}int ret = 0;for(int j = 0; j < 3; j++)ret = max(ret, g[n - 1][j]);return ret;}
};

188. 买卖股票的最佳时机 IV

题目】:188. 买卖股票的最佳时机 IV

在这里插入图片描述

算法思路

首先处理 k 的值,考虑到 k 可能超过所需的总天数,通过数学方法将 k 调整到一个合理范围内。

在这里插入图片描述

这道题算法思路同上道题一样,主要画出"状态机"分析状态转移方程,同时需要分析状态转移方程出现的问题。

在这里插入图片描述

代码实现

class Solution {
public:const int INF = -0x3f3f3f3f;int maxProfit(int k, vector<int>& prices) {     int n = prices.size();       k = min(k, n/2);//1.创建dp表      vector<vector<int>> f(n, vector<int>(k + 1, INF));auto g = f;//2.初始化f[0][0] = -prices[0];g[0][0] = 0;//3.填表操作for(int i = 1; i < n; i++){for(int j = 0; j <= k; j++){f[i][j] = max(f[i - 1][j], g[i - 1][j] - prices[i]);g[i][j] = g[i - 1][j];if(j - 1 >= 0)g[i][j] = max(g[i][j], f[i - 1][j - 1] + prices[i]);}}int ret = 0;for(int j = 0; j <= k; j++) ret = max(ret, g[n - 1][j]);return ret;}
};

在这里插入图片描述
快和小二一起踏上精彩的算法之旅!关注我,我们将一起破解算法奥秘,探索更多实用且有趣的知识,开启属于你的编程冒险!

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

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

相关文章

【HTTP】防XSS+SQL注入:自定义HttpMessageConverter过滤链深度解决方案

防XSSSQL注入&#xff1a;自定义HttpMessageConverter过滤链深度解决方案一、安全威胁模型分析二、自定义HttpMessageConverter架构设计2.1 技术栈组成三、完整实现代码3.1 安全过滤工具类3.2 自定义HttpMessageConverter3.3 Spring安全配置四、深度防御增强方案4.1 SQL注入参数…

学习游戏制作记录(冻结敌人时间与黑洞技能)7.30

1.实现剑击中敌人时冻结敌人时间Enemy脚本&#xff1a;public float defaultMoveSpeed;//默认速度defaultMoveSpeed moveSpeed;//Awake&#xff08;&#xff09;中设置public virtual void FreezeTime(bool _timeFreeze)//冻结设置函数{if (_timeFreeze){moveSpeed 0;anim.sp…

【数据结构】真题 2016

待补充已知表头元素为c的单链表在内存中的存储状态如下表所示地址元素链接地址1000Ha1010H1004Hb100CH1008Hc1000H100CHdNULL1010He1004H1014H现将f存放于1014H处并插入到单链表中&#xff0c;若f在逻辑上位于a和e之间&#xff0c;则a, e, f的“链接地址”依次是&#xff08; &…

双线串行的 “跨界对话”:I2C 与 MDIO 的异同解析

在电子系统设计中,串行总线凭借其精简的信号线数量和灵活的拓扑结构,成为芯片间通信的主流选择。I2C(Inter-Integrated Circuit)和 MDIO(Management Data Input/Output)作为两种典型的双线串行总线,虽同属低速信号范畴,却在各自的应用领域扮演着不可替代的角色。本文将…

算法精讲:二分查找(二)—— 变形技巧

&#x1f3af; 算法精讲&#xff1a;二分查找&#xff08;二&#xff09;—— 变形技巧 &#x1f50d; 友情提示&#xff1a;&#xff1a;本小节含高能代码片段 &#x1f964; 阅读前请确保已掌握基础二分原理与实现代码片段可能包含不同程度的变形&#xff0c;请根据实际情况选…

两个程序配合实现了基于共享内存和信号量的进程间通信,具体说明如下:

第一个程序&#xff1a;共享内存读取程序&#xff08;消费者&#xff09;该程序作为消费者&#xff0c;从共享内存中读取数据&#xff0c;通过信号量保证只有当生产者写入数据后才能读取。/*4 - 读共享内存*/ #include<stdio.h> // 标准输入输出库 #inc…

JeecgBoot(1):前后台环境搭建

1 项目介绍 JeecgBoot 是一款基于 Java 的 AI 低代码平台&#xff0c;它采用了 SpringBoot、SpringCloud、Ant Design Vue3、Mybatis 等技术栈&#xff0c;并集成了代码生成器、AI 对话助手、AI 建表、AI 写文章等功能。JeecgBoot 的设计宗旨是实现简单功能零代码开发&#xf…

Nestjs框架: 关于 OOP / FP / FRP 编程

概述 在软件开发过程中&#xff0c;不同的编程范式为我们提供了多样化的思维方式与实现路径它们不仅影响着代码的结构和逻辑组织方式&#xff0c;也深刻影响着项目的可维护性、可扩展性以及团队协作效率 什么是 OOP、FP 和 FRP&#xff1f;首先从三个术语的含义入手 1 &#xf…

elememtor 添加分页功能

各位看官好&#xff0c;最近在忙着使用elementor搭建自己的网站&#xff0c;由于我不是专业的程序员和前端&#xff0c;又没有很多钱去找外包公司实现自己的设计&#xff0c;所以选择了elementor. 总的来说这是一个不错的wordpress 插件&#xff0c;也让我们这种非专业的网站设…

关于“PromptPilot” 之2 -目标系统:Prompt构造器

目标系统&#xff1a;Prompt构造器想法首先&#xff0c;在抽象层对PromptPilot进行封装给出提示词形成过程的全部环节。然后&#xff0c;在 形成一套确定的提示词后再为 小规模试点方案生成一整套开发工具并配套集成开发环境和指南。最后&#xff0c;在小规模试点成功后进行拓展…

短剧小程序系统开发:重塑影视内容消费格局

在数字化浪潮的推动下&#xff0c;影视内容消费正经历着深刻的变革。短剧小程序系统开发作为这一变革的重要力量&#xff0c;正在重塑影视内容消费的格局&#xff0c;为用户带来更加个性化、便捷化的观影体验。传统影视内容消费往往受到时间和空间的限制&#xff0c;用户需要前…

一文掌握最新版本Monocle3单细胞轨迹(拟时序)分析

许多大佬的软件想要构建一个大而美的生态&#xff0c;从 monocle2 开始就能做单细胞的质控、降维、分群、注释这一系列的分析&#xff0c;但不幸的是我们只知道 monocle 系列还是主要做拟时序分析&#xff0c;一方面是因为 Seurat 有先发优势&#xff0c;出名要趁早&#xff0c…

spark入门-helloword

我们学习编程语言的时候&#xff0c;第一个程序就是打印一下 “hello world” &#xff0c;对于大数据领域的第一个任务则是wordcount。那我们就开始我们的第一个spark任务吧&#xff01; 下载spark 官方下载地址&#xff1a;Apache Download Mirrors 下载完毕以后&#xff0c…

雷达系统设计学习:自制6GHz FMCW Radar

国外大神自制6GHZ FMCW Radar开源项目: https://github.com/Ttl/fmcw3 引言 之前我做过一个简单的调频连续波&#xff08;FMCW&#xff09;雷达&#xff0c;能够探测到100米范围内人体大小的物体。虽然它确实能用&#xff0c;但由于预算有限&#xff0c;还有很大的改进空间。 …

系统选择菜单(ubuntu grub)介绍

好的&#xff0c;我们来详细解释一下什么是Ubuntu的GRUB菜单。 简单来说&#xff0c;GRUB菜单是您电脑启动时看到的第一个交互界面&#xff0c;它就像一个“系统选择”菜单&#xff0c;让您决定接下来要启动哪个操作系统或进入哪种模式。详细解释 1. GRUB是什么&#xff1f; GR…

方案C,version2

实现一个简单的Helloworld网页,并通过GitHub Actions自动构建并推送到公开仓库的gh-pages分支。同时,使用PAT进行认证,确保源码在私有仓库中,构建后的静态文件在公开仓库中。 重新设计deploy.yml内容如下(针对纯静态文件,无需构建过程): 步骤: 检出私有仓库源码。 由于…

R 语言科研绘图 --- 其他绘图-汇总1

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…

webpack 原理及使用

【点赞收藏加关注,前端技术不迷路~】 一、webpack基础 1.核心概念 1)entry:定义入口,webpack构建的第一步 module.exports ={entry:./src/xxx.js } 2)output:出口(输出) 3)loader:模块加载器,用户将模块的原内容按照需求加载成新内容 比如文本加载器raw-loade…

「日拱一码」039 机器学习-训练时间VS精确度

目录 时间-精度权衡曲线&#xff08;不同模型复杂度&#xff09; 训练与验证损失对比 帕累托前沿分析&#xff08;3D&#xff09; 在机器学习实践中&#xff0c;理解模型收敛所需时间及其与精度的关系至关重要。下面介绍如何分析模型收敛时间与精度之间的权衡&#xff0c;并…

面试刷题平台项目总结

项目简介&#xff1a; 面试刷题平台是一款基于 Spring Boot Redis MySQL Elasticsearch 的 面试刷题平台&#xff0c;运用 Druid HotKey Sa-Token Sentinel 提高了系统的性能和安全性。 第一阶段&#xff0c;开发基础的刷题平台&#xff0c;带大家熟悉项目开发流程&#xff…