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

news2024/12/21 13:49:12

动态规划算法专辑之多状态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]这类的值

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

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

相关文章

节省时间、提升效率——Jetpack关爱你的摸鱼时间

JetPack Jetpack 是一个由 Google 提供的 Android 应用开发库集合。它旨在简化 Android 应用程序开发过程&#xff0c;提供一系列的库和工具&#xff0c;帮助开发者快速构建高质量、健壮、可扩展的 Android 应用。 Jetpack 包含多个组件&#xff0c;每个组件都专注于不同的功…

Nginx 的reload,升级以及关闭流程

一、reload流程 1 向master进程发送HUP信号&#xff08;reload命令&#xff09; 2 master进程校验配置语法是否正确&#xff1b; 3 master打开可能引入的新的监听端口&#xff1b; 4 master用新的配置文件启动新的worker子进程&#xff1b; 5 启动新的worker子进程之后&#x…

小马赠书【第8期】清华社 618 IT BOOK 多得活动(送书5本)

本期 敬 之 共精心挑选了 15 本 IT 相关书籍&#xff0c;包含 前端、后端、数据分析、人工智能、python 等各个领域。关于如何参与等具体活动信息请看活动详情页&#xff0c;以下是 15 本 IT 书籍介绍&#xff1a; 活动详情页&#xff1a;小马赠书【第8期】 1. 《Linux设备驱动…

怎么入手性能测试,重点以及各项流程

之前在性能测试学习路线里&#xff0c;提到过《软件性能测试、分析与调优实践之路》这本书。 昨天看到之前自己记的读书笔记&#xff0c;整理一下发出来&#xff0c;希望对读者有所帮助。 网上关于性能测试的文章大多数时间比较久远&#xff0c;或者知识点比较散&#xff0c;…

南大一作!科学家发现全新量子态 | Nature速递

光子盒研究院 马萨诸塞大学助理教授Tigran Sedrakyan在内的一个物理学家团队最近在《自然》杂志上宣布&#xff0c;他们已经发现了一种新的物质阶段——“手性玻色液态(chiral Bose-liquid state)”&#xff0c;这一突破为理解物理世界本质的古老努力开辟了一条全新道路。 团队…

【目标跟踪】MOT数据集GroundTruth可视化

MOT数据集格式简介 MOT15数据集下载&#xff1a;https://pan.baidu.com/s/1foGrBXvsanW8BI4eybqfWg?pwd8888 以下为一行gt示例&#xff1a; 1,1,1367,393,73,225,1,-1,-1,-1 各列数据对应含义如下 <frame>,<id>,<bb_left>,<bb_top>,<bb_width&g…

autocut

在讲 OpenAI Whisper 前先做了一个剪视频小工具【论文精读44】_哔哩哔哩_bilibili更多论文&#xff1a;https://github.com/mli/paper-reading, 视频播放量 58633、弹幕量 233、点赞数 2732、投硬币枚数 1630、收藏人数 1465、转发人数 604, 视频作者 跟李沐学AI, 作者简介 &am…

什么是python,一篇带你详细了解Python

Python是一种跨平台的计算机程序设计语言&#xff0c;是ABC语言的替代品&#xff0c;属于面向对象的动态类型语言&#xff0c;最初被设计用于编写自动化脚本&#xff0c;随着版本的不断更新和语言新功能的添加&#xff0c;越来越多被用于独立的、大型项目的开发。 python前景…

挖掘用户真实需求 避坑5大技巧

1、用户总是“说一套 做一套” 在进行需求市场调研时&#xff0c;我们问1000个用户&#xff0c;是否想要黄金&#xff0c;几乎所有的用户都是肯定的回答。如果我们以此认定&#xff0c;黄金是用户的真实需求会过于草率。 我们需继续追问用户&#xff1a;买黄金做什么&#xff1…

【微信小程序开发】第 7 课 - 小程序的组件

欢迎来到博主 Apeiron 的博客&#xff0c;祝您旅程愉快 &#xff01; 时止则止&#xff0c;时行则行。动静不失其时&#xff0c;其道光明。 目录 1、缘起 2、小程序中组件的分类 3、常用的视图容器类组件 3.1、view 组件 3.2、scroll - view 组件 3.3、swiper 和 swiper…

【youcans动手学模型】Xception 模型-CIFAR10图像分类

欢迎关注『youcans动手学模型』系列 本专栏内容和资源同步到 GitHub/youcans 【youcans动手学模型】Xception 模型-CIFAR10图像分类 1. Xception 神经网络模型1.1 模型简介1.2 论文介绍1.3 分析与讨论 2. 在 PyTorch 中定义 Xception 模型类2.1 深度可分离卷积2.2 带残差连接的…

【九章斩题录】从尾到头打印链表(JZ6)

精品题解 &#x1f525; 《九章斩题录》 &#x1f448; 猛戳订阅 目录 JZ6 - 从尾到头打印链表 「 法一 」链表元素存入数组后再反转 「 法二 」递归大法 「 法三 」栈 JZ6 - 从尾到头打印链表 &#x1f4da; 题目&#xff1a;输入一个链表的头节点&#xff0c;按链表从…

苹果iOS 17新功能:重置密码 72 小时内可使用旧密码再次重置

一些用户可能会遇到&#xff0c;在修改了 iPhone 密码之后&#xff0c;突然忘记新密码的情况。现在苹果在 iOS 17 中加入了新的解决方案&#xff1a;在重置密码的 72 小时之内&#xff0c;如果用户不小心忘记了新设置的密码&#xff0c;仍然可以使用旧密码进行再次重置。 在重…

TS系列之工具类型Partial、Required、Pick、Record详解,示例

TS系列之工具类型Partial、Required、Pick、Record详解&#xff0c;示例 文章目录 前言一、Partial<Type>二、Required<Type>三、Pick<Type, Keys>四、Record<Keys, Type>总结 前言 本片文章主要利用上一篇所学的keyof做一个延申与扩展的学习。在Type…

OpenGaussDB2.0.1

目录 1. GaussDB版本2. OpenGaussDB介绍3. 单节点安装3.1 环境配置3.2 安装 4. 远程连接设置 1. GaussDB版本 GaussDB的版本&#xff1a; GaussDB 100&#xff1a;目前暂不发布&#xff0c;公司合作伙伴需向华为提交申请&#xff08;GaussDB 100 将在 2020 年被正式命名为 Gaus…

Redis入门 - 3种特殊数据类型

原文首更地址&#xff0c;阅读效果更佳&#xff01; Redis入门 - 3种特殊数据类型 | CoderMast编程桅杆https://www.codermast.com/database/redis/three-special-datatype.html 在我们平常的业务中基本只会使用到Redis的基本数据类型&#xff08;String、List、Hash、Set、S…

浅谈.NET语言开发应用领域

.NET语言是一种跨平台的开发框架&#xff0c;适用于各种应用程序的开发。以下是一些常见的.NET语言开发应用领域&#xff1a; 桌面应用程序开发&#xff1a;使用.NET框架开发的桌面应用程序可以在Windows操作系统上运行&#xff0c;包括Windows Forms和WPF。这些应用程序可以用…

CentOS开机报错““error can‘t find command ‘:‘“处理方法

CentOS开机报错"error cant find command :"处理方法 本文为故障描述和问题记录。converterP2V迁移CentOS7到虚拟机&#xff0c;开机报错"error can’t find command ‘:’"的处理方法。 本文为CentOS7的操作记录&#xff0c;其他版本可以参考&#xff0c;…

CASAIM光学彩色三维扫描仪助力文物艺术品三维数字化3D打印

文物艺术品数字化&#xff0c;实际上是一种文物艺术品信息的记录方式&#xff0c;除了运用视频、照片、录音等多媒体形式将某些文物进行记录外&#xff0c;文物艺术品数字化主要是指针对有形文化遗产采用非接触式扫描得到的三维数字化记录&#xff0c;通过实景三维建模&#xf…

GitHub 上传自己的项目

文章目录 前言一、步骤1.GitHub 创建项目2.Git 上传本地项目到 GitHub3.Git 命令整理 总结 前言 不附 Demo 连接的博客不是好博客&#xff0c;所以我们要做个乐于助人&#xff0c;有责任心的人&#xff0c;这篇文章手把手教你如何在 GitHub 上传自己的项目&#xff0c; 一、步…