动态规划算法(多状态dp1)

动态规划算法专辑之多状态dp问题(1)

一、什么是多状态

多状态dp问题,指一个规模问题下存在多种状态,我们需要联合关注多种状态间的相互转移,才可以求解目的问题。

多状态问题可以理解为有限状态机,在有限的状态中转换,解决这类问题最重要的就是画出状态转移图

二、最佳买卖股票时机含冷冻期

image-20230616154823156

1.题目解析

针对于题目给的test case有如下分析:

image-20230616155547798

2.状态定义

根据经验+题目要求,dp[i]可以表示为:以i为结尾时的最大利润

和斐波那契数列子问题分析一样,对于斐波那契来说,相减后的值会有多个,而这是有多种状态可能会导致一样dp[i],因此算出来的dp[i]是无法知道之前的状态的,也就是不确定的,因此我们对于该问题,我们也应该定义一个二维的dp表

新的状态定义:

dp[i] [0]表示;第i天结束之后,处于买入状态可获得的最大利润

dp[i] [1]表示:第i天结束之后,处于可交易状态可获得的最大利润

dp[i] [2]表示:第i天结束之后,处于冷冻状态可获得的最大利润

3.状态转移方程

对于多状态问题而言,我们首先要画出状态转移图

状态转移图的几个核心要点:

  1. 本状态能不能到本状态
  2. 本状态能到什么状态,发生什么变化
  3. 什么状态能到本状态

本题的状态图如下:

image-20230616161534517

由此可得状态转移方程:

image-20230616161943016

有了状态转移图,状态转移方程就能很轻松的写出来了

4.初始化

首先进入的必定是买入状态,因此只需要初始化dp[0] [0]即可

dp[0] [0] = -prices[0]

5.填表顺序

根据状态转移方程,我们可以很清晰的看到,i受i-1的影响,因从左往右进行填表

6.返回值

由于i走到最后一步时可能处于三种状态的其中一种,所以取所有状态里的最大值

7.代码实现

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n = prices.size();
        vector<vector<int>> dp(n,vector<int>(3));
        dp[0][0] = -prices[0];
        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][2],dp[i-1][1]);
            dp[i][2] = dp[i-1][0] + prices[i];
        }

        int ans = 0;
        for(int i=0;i<3;i++)
        {
            ans = max(ans,dp[n-1][i]);
        }

        return ans;
    }
};

三、买卖股票的最佳时机IV

image-20230616162731108

1.题目解析

买入并卖出视为一次交易,k次交易内可获得的最大利润

image-20230616163512509

2.状态定义

根据经验+题目要求,dp[i]可以表示为:i天之后,可获得的最大利润

同时,也基于前面几题的分析,显而易见这是不可行的,i天可以处于两种状态,买入或卖出,也可能是第t次交易

因此,我们因对买入和卖出定义两个二维dp表

新的状态定义:

f[i] [j]:i天结束之后,完成了j次交易,,处于买入状态,所获得的最大利润

g[i] [j]:i天结束之后,完成了j次交易,,处于卖出状态,所获得的最大利润

3.状态转移方程

本题只有两种状态,状态转移图如下:

image-20230616164417266

由此图可得状态转移方程:

image-20230616164712501

4.初始化

同样,首先进入的必定是买入状态

f[0] [0] = -prices[0]

填表从i=1开始,因此g[0] [0] 也得初始化

g[0] [0] = 0

5.填表顺序

i受i-1的影响,因此从左到右进行填表

交易次数是逐步增加的,因此从上到下填表

6.返回值

k次交易内的最大利润,f表并没有完成一次完整的交易,所以肯定不可能出现最大利润

只需对g表进行k次遍历,找出最大值即可

7.代码实现

有2个细节问题:

k次交易可能完全达不到:

天数为20天,交易次数k为30次,对于20天,最多只能进行10次交易,一定不可能出现30次交易的情况

因此我们可以对k进行优化,来省略一定的时间和空间

基于前面的经验,我们很可能会将dp表初始化为INT_MAX或INT_MIN,但这样一旦执行加法或者减法,会发生值越界的问题,因此我们一般初始化为0x3f3f3f3f

class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        const int INF = 0x3f3f3f3f;
        int n = prices.size();
        k = min(n/2,k);
        vector<vector<int>> f(n,vector<int>(k+1,-INF));
        auto g = f;
        f[0][0] = -prices[0];
        g[0][0] = 0;
        
        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)
                    g[i][j] = max(g[i-1][j],f[i-1][j-1]+prices[i]);
            }
        }

        int res = 0;
        for(int i=0;i<=k;i++)
            res = max(res,g[n-1][i]);
        return res;
    }
};

四、总结

多状态dp问题的核心就是找可能出现的所有状态并找出状态之间是如何转换的,只要画出了状态转移图,问题也就迎刃而解了,同时还要注意返回值的问题,因根据最后一步操作后可能处于的状态来确定返回值,不要盲目的返回诸如dp[n]这类的值

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

centos 7 安装git并配置ssh

一、安装 1、查看是否安装git <span style"color:#333333"><span style"background-color:#ffffff"><code class"language-perl">rpm -qa|<span style"color:#0000ff">grep</span> git </code>…

边缘检测笔记

边缘是什么&#xff1f; 图像的边缘是指图像局部区域中亮度变化明显的部分&#xff0c;边缘位于像素的灰度值产生突变的地方。 边缘的正负之分&#xff1a;由暗到亮为正&#xff0c;由亮变暗为负。 图像的高频信号和低频信号 简单理解为&#xff0c;图像中高频分量&#xff08…

mcu:利用Cortex-M中的DWT实现高精度计时

1、Cortex-M中的DWT 在Cortex-M里面有一个外设叫DWT(Data Watchpoint and Trace)&#xff0c;是用于系统调试及跟踪。 它有一个32位的寄存器叫CYCCNT&#xff0c;它是一个向上的计数器&#xff0c;记录的是内核时钟运行的个数&#xff0c;内核时钟跳动一次&#xff0c;该计数器…

YOLOV5 训练

YOLOV5训练过程 CUDA 和cuDnnan 安装教程 windows上安装可以参考这篇知乎文章 数据集准备 自己准备数据集 可以使用 labelImg 工具&#xff0c;直接 pip install labelimg 就可以安装了。 命令行中输入 labelImg 就可以运行 标注数据的输出结果有多种过格式&#xff0c;V…

前端什么最难学?

前言 个人认为是JS&#xff0c;无论是在平时的项目或者找工作时候JS都是大头&#xff0c;相比起其他的部分&#xff0c;它相对而言是难一点&#xff0c;同时也是十分重要的一部分&#xff0c;学好原生JS&#xff0c;后续的学习才能基于此循序渐进&#xff0c;下面是我总结的关…

GIT学习笔记

团队使用GIT有些时间了&#xff0c;也遇到一些问题&#xff1a; 遇到大量冲突&#xff0c;解决完之后&#xff0c;没有修改的代码也变成蓝色了&#xff0c;如果不push&#xff0c;代码将会丢失代码丢失&#xff08;具体情况&#xff0c;我暂时记不清了&#xff09;git push失败…

数据库入门下篇(如何安装和登录MYSQL数据库)

在这篇文章里&#xff0c;笔者将着重讲解如何在win和Linux系统上安装自己的MySQL数据库软件&#xff0c;以及安装好数据库软件后如何启动和登录&#xff0c;忘了密码怎么办&#xff1f;如何创建一个数据库&#xff0c;如何在数据库中创建一个表等内容 目录 在windows系统上安装…

HNU计算机体系结构-实验一:RISC-V指令理解

HNU计算机体系结构-实验一 前言1.实验目的2.实验步骤1.安装模拟器Ripes2.生成汇编指令3.思考问题1&#xff09;指令add x15, x14, x152&#xff09;指令bge x15 x14 -683&#xff09;指令lw x15, -20 x84&#xff09;指令sw x15, -20 x85&#xff09;简述BranchE信号的作用6&am…

中级前端笔试面试题总结

typeof null 的结果是什么&#xff0c;为什么&#xff1f; typeof null 的结果是Object。 在 JavaScript 第一个版本中&#xff0c;所有值都存储在 32 位的单元中&#xff0c;每个单元包含一个小的 类型标签(1-3 bits) 以及当前要存储值的真实数据。类型标签存储在每个单元的…

(浙大陈越版)数据结构 第三章 树(中) 二叉搜索树和平衡二叉树

目录 4.1.1 二叉搜索树及查找 什么是二叉搜索树 定义 二叉搜索树特殊函数集&#xff1a; 查找操作&#xff1a;Find 算法思想 代码实现 补&#xff1a;查找最大和最小元素 4.1.2 二叉搜索树的插入 插入操作&#xff1a;Insert 算法思想 代码实现 例题 4.1.3 二叉…

吴恩达老师《机器学习》课后习题1之线性回归

在学习这些内容之前&#xff0c;需要学习python数据分析相关内容&#xff1a; numpy&#xff1a;科学计算库&#xff0c;处理多维数组&#xff0c;进行数据分析 pandas&#xff1a;基于numpy的一种工具&#xff0c;该工具是为了解决数据分析任务而创建的 matplotlib&#xff1a…

如何进行微服务测试?

微服务测试是一种特殊的测试类型&#xff0c;因为它涉及到多个独立的服务。以下是进行微服务测试的一般性步骤&#xff1a; 1. 确定系统架构 了解微服务架构对成功测试至关重要。确定每个微服务的职责、接口、依赖项和通信方式。了解这些信息可以帮助您更好地规划测试用例和测…

Aop详解

AOP简介 AOP是一种编程思想&#xff0c;就如同面向对象这种编程思想一样&#xff0c;是一种编程范式&#xff0c;用来指导开发者如何组织程序更好的运行 AOP&#xff08;面向切面编程&#xff09; 作用&#xff1a;在不改变原代码的前提下&#xff0c;为其增加功能。 连接点…

Apikit 自学日记:导入第三方产品 API 数据

除了手动创建API文档&#xff0c;系统也提供了一键导入 Swagger、Postman、RAP、YAPI 等产品数据的功能。方便从其他平台进行迁移。 产品支持度导入文件的后缀名Eolinker API 研发管理完全支持.jsonPostman V2.1支持导入API基础信息&#xff0c;超过10级分组的API数据将不会被导…

git在windows及linux(源码编译)环境下安装

git在windows及linux(源码编译)环境下安装 环境信息: 系统版本:CentOS Linux release 7.9.2009 (Core) git指令安装: yum install -y git 一、git在windows下安装 下载地址:https://git-scm.com/ 默认安装即可 验证 git --version 二、git在linux下安装 下载地址…

游戏场景的转换——状态模式

状态模式 游戏比较复杂时&#xff0c;通常会设计成多个场景。 切换场景的好处 1、重复使用场景 跳转切换场景的代码有两种一种是旧版的方法 Application.LoadLevel(“SampleScene”);另一种是新版的方法 SceneManager.LoadScene(“SampleScene”); 例子1&#xff1a;通过场景…

【QT】TCP/UDP详解及实现

TCP/UDP TCP/IP模型TCP协议头部格式三次握手四次挥手 UDP协议头部格式 Socket编程tcpudp代码实现服务端&#xff1a;客户端&#xff1a; 总结 TCP/IP模型 TCP模型是一个常见的网络协议参考模型&#xff0c;也称为TCP/IP模型或互联网模型。它是指TCP/IP协议族中的一组协议&…

Creating Add-in Hooks (C#)

本文介绍如何使一个文件在添加、检入、检出到库时&#xff0c;让add-in 程序在SOLIDWORKS PDM Professional 中通知到你。 注意&#xff1a; 因为 SOLIDWORKS PDM Professional 无法强制重新加载Add-in程序 &#xff0c;必须重新启动所有客户端计算机&#xff0c;以确保使用最…

【Python开发】FastAPI 09:middleware 中间件及跨域

FastAPI 提供了一些中间件来增强它的功能&#xff0c;类似于 Spring 的切面编程&#xff0c;中间件可以在请求处理前或处理后执行一些操作&#xff0c;例如记录日志、添加请求头、鉴权等&#xff0c;跨域也是 FastAPI 中间件的一部分。 目录 1 中间件 1.1 创建中间件 1.2 使…

MySQL常见问题

优化慢查询 慢查询可能出现的情况&#xff1a; 聚合查询多表查询表数据量过大深度分页查询 表象&#xff1a;页面加载过慢&#xff0c;接口压测响应时间过长&#xff08;超过1s&#xff09; 如何定位慢查询&#xff1f; 方案一&#xff1a;开源工具 可以使用相应的调试工具&a…