[Algorithm][动态规划][简单多状态DP问题][买卖股票的最佳时机 III][买卖股票的最佳时机 Ⅳ]详细讲解

目录

  • 1.买卖股票的最佳时机 III
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 2.买卖股票的最佳时机 IV
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现


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

1.题目链接

  • 买卖股票的最佳时机 III

2.算法原理详解

  • 注意:本题为了便于初始化,有较多细节服务于它
  • 思路
    • 确定状态表示 -> dp[i]的含义

      • i天结束之后,所能获得的最大利润
      • 本题,状态表示还可以继续细分:
        • f[i][j]:第i天结束之后,完成了j次交易,处于“买入”状态,此时的最大利润
        • g[i][j]:第i天结束之后,完成了j次交易,处于“卖出”状态,此时的最大利润
          请添加图片描述
    • 推导状态转移方程:本题关系复杂,可以画图辅助

      • f[i][j] = max(f[i - 1][j], g[i - 1][j] - p[i])
      • g[i][j] = max(g[i - 1][j], f[i - 1][j - 1] + p[i])
        • 初始化时,只有g需要特殊处理第一列,而f并不需要
        • 为了避免这种情况,可以将这个状态方程拆成多步,分步执行
          • g[i][j] = g[i - 1][j]
          • if(j - 1 >= 0) g[i][j] = max(g[i][j], f[i - 1][j - 1] + p[i])
            请添加图片描述
    • 初始化:vector<vector<int>> dp[i][[j](n, vector<int>(3, -INF))

      • f[0][0] = -p[0], g[0][0] = 0
      • INF = 0x3f3f3f3f
      • 为什么这里用-INF而不是INT_MIN
        • 因为本题状态方程中,有减法,可能在最开始时,对INT_MIN减一个数,此时会溢出
        • 所以选择-INF,首先它足够小,其次没有溢出风险
          请添加图片描述
    • 确定填表顺序:从上往下,从左往右,两个表一起填

    • 确定返回值:g[n - 1]中的最大值

  • 本题可以吸收积累的知识点
    • 算法里面初始化为无穷:INT_MAX || INT_MIN时,要注意潜在的溢出风险
      • 替换为0x3f3f3f3f || -0x3f3f3f3f即可解决该问题
      • 首先它足够大,其次它没有溢出风险
    • 多个状态方程,其中只有一部分的状态方程需要特殊的初始化,那么可以想办法把这个状态方程拆成多步,分步执行,尝试避免特殊处理初始化

3.代码实现

int maxProfit(vector<int>& prices) 
{
    const int INF = -0x3f3f3f3f; // 充当"INT_MIN"的角色

    int n = prices.size();
    vector<vector<int>> f(n, vector<int>(3, INF));
    vector<vector<int>> g(n, vector<int>(3, INF));
    f[0][0] = -prices[0], g[0][0] = 0;

    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]时,要防止越界
            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 < 3; j++)
    {
        ret = max(ret, g[n - 1][j]);
    }

    return ret;
}

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

1.题目链接

  • 买卖股票的最佳时机 IV

2.算法原理详解

  • 注意:本题为了便于初始化,有较多细节服务于它
  • 本题思路与买卖股票的最佳时机 III几乎一致,无非是限制次数变了
  • 细节:可能k > n / 2,此时开空间时,会多开很多无意义的空间
    • 此时k = min(k, n / 2)可以解决该问题
  • 思路
    • 确定状态表示 -> dp[i]的含义

      • i天结束之后,所能获得的最大利润
      • 本题,状态表示还可以继续细分:
        • f[i][j]:第i天结束之后,完成了j次交易,处于“买入”状态,此时的最大利润
        • g[i][j]:第i天结束之后,完成了j次交易,处于“卖出”状态,此时的最大利润
          请添加图片描述
    • 推导状态转移方程:本题关系复杂,可以画图辅助

      • f[i][j] = max(f[i - 1][j], g[i - 1][j] - p[i])
      • g[i][j] = max(g[i - 1][j], f[i - 1][j - 1] + p[i])
        • 初始化时,只有g需要特殊处理第一列,而f并不需要
        • 为了避免这种情况,可以将这个状态方程拆成多步,分步执行
          • g[i][j] = g[i - 1][j]
          • if(j - 1 >= 0) g[i][j] = max(g[i][j], f[i - 1][j - 1] + p[i])
            请添加图片描述
    • 初始化:vector<vector<int>> dp[i][[j](n, vector<int>(3, -INF))

      • f[0][0] = -p[0], g[0][0] = 0
      • INF = 0x3f3f3f3f
      • 为什么这里用-INF而不是INT_MIN
        • 因为本题状态方程中,有减法,可能在最开始时,对INT_MIN减一个数,此时会溢出
        • 所以选择-INF,首先它足够小,其次没有溢出风险
          请添加图片描述
    • 确定填表顺序:从上往下,从左往右,两个表一起填

    • 确定返回值:g[n - 1]中的最大值

  • 本题可以吸收积累的知识点
    • 算法里面初始化为无穷:INT_MAX || INT_MIN时,要注意潜在的溢出风险
      • 替换为0x3f3f3f3f || -0x3f3f3f3f即可解决该问题
      • 首先它足够大,其次它没有溢出风险
    • 多个状态方程,其中只有一部分的状态方程需要特殊的初始化,那么可以想办法把这个状态方程拆成多步,分步执行,尝试避免特殊处理初始化

3.代码实现

int maxProfit(int k, vector<int>& prices) 
{
    const int INF = -0x3f3f3f3f; // 替代"INT_MIN"的功能
    int n = prices.size();

    // 优化处理细节,避免空间浪费
    k = min(k, n / 2);

    vector<vector<int>> f(n, vector<int>(k + 1, INF));
    vector<vector<int>> g(n, vector<int>(k + 1, INF));
    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时,要避免越界
            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 i = 0; i <= k; i++)
    {
        ret = max(ret, g[n - 1][i]);
    }

    return ret;
}

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

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

相关文章

Java之Writer类:探索Java中的输出流

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

在CentOS 8上卸载与安装MySQL 8的详细步骤

关键词&#xff1a;MySQL 8安装、CentOS 8、YUM源配置、卸载MySQL、MySQL残留文件删除、首次登录MySQL临时密码、服务状态检查、MySQL社区服务器 阅读建议&#xff1a;本文适合需要在CentOS 8操作系统上部署最新MySQL 8数据库的系统管理员或开发者阅读。文中步骤简洁清晰&#…

Spring+SpringBoot面试总结(近两万字)

SpringSpringBoot面试总结 一、Spring Bean1.1、bean的生命周期&#xff08;对象的创建使用销毁&#xff09;1.1.1、准备工作1.1.2、创建Bean对象1.1.3、注册销毁 1.2、 bean的作用域1.2.1、配置方式 1.3、 spring 自动装配 bean 有哪些方式&#xff08;存疑存疑&#xff09;1.…

452. 用最少数量的箭引爆气球(中等)

452. 用最少数量的箭引爆气球 1. 题目描述2.详细题解3.代码实现3.1 Python3.2 Java 1. 题目描述 题目中转&#xff1a;452. 用最少数量的箭引爆气球 2.详细题解 引爆所有气球&#xff0c;弓箭数要最少&#xff0c;那么每支弓箭尽量多的引爆气球&#xff0c;采用贪心策略。对于…

基于小波熵阈值的心电信号R波检测算法(MATLAB)

心脏兴奋电活动过程可由心电信号(ECG)来反映&#xff0c;心电信号也是医学上对心血管疾病诊断的重要科学依据。心电信号具有一定的随机性且一般情况下十分微弱&#xff0c;在信号采集、放大及变换过程中&#xff0c;心电信号容易受到人体呼吸及检测仪器等因素影响&#xff0c;从…

在ARM开发板上,栈大小设置为2MB(常用设置)里面存放的数据

系列文章目录 在ARM开发板上&#xff0c;栈大小设置为2MB&#xff08;常用设置&#xff09;里面存放的数据 在ARM开发板上&#xff0c;栈大小设置为2MB&#xff08;常用设置&#xff09;里面存放的数据 系列文章目录 在ARM开发板上&#xff0c;栈&#xff08;Stack&#xff09;…

linux下cp和mv命令显示进度条

1.查看当前系统下coreutils工具包的版本号&#xff1a; [rootk8s-master ~]# rpm -qa | grep -w coreutils coreutils-8.22-24.el7_9.2.x86_64当前版本为8.22。 因为cp 和 mv 命令由 coreutils 软件包提供&#xff0c;所以需要重新下载 coreutils 软件包配置补丁 2.下载core…

148.栈与队列:前K个高频元素(力扣)

代码解决 class Solution { public:// 自定义比较类&#xff0c;用于优先队列&#xff08;小顶堆&#xff09;class mycomparison{public:// 重载操作符&#xff0c;用于比较两个pair&#xff0c;基于pair的第二个值&#xff08;频率&#xff09;bool operator()(const pair&l…

网页图片加载慢的求解指南

网页/图片加载慢的求解指南 一、前言与问题描述 今天刚换上华为的HUAWEI AX3 Pro New&#xff0c;连上WIFI后测速虽然比平时慢&#xff0c;但是也不算太离谱&#xff0c;如下图所示&#xff1a; 估计读者们有也和作者一样&#xff0c;还没意识到事情的严重性&#x1f601;。 …

UE_地编教程_创建地形洞材质

个人学习笔记&#xff0c;不喜勿喷。侵权立删&#xff01; 使用地形洞材质来遮罩地形上特定位置的可视性和碰撞。如要在山脉侧面创建进入洞穴的入口&#xff0c;此操作将非常有用。可使用地形材质和地形洞材质的相同材质&#xff0c;但注意&#xff1a;对比不使用不透明蒙版的…

基于Cloudflare/CloudDNS/GitHub使用免费域名部署NewBing的AI服务

部署前准备&#xff1a; Cloudflare 账号 https://dash.cloudflare.com/login CloudDNS 账号 https://www.cloudns.net/ GitHub 账号 https://github.com/Harry-zklcdc/go-proxy-bingai Cloudflare 部署 Worker CloudDNS 获取免费二级域名 GitHub New Bing Ai 项目 https://git…

Linux系统硬盘分区

文章目录 一、硬盘和分区1.1 硬盘的概念1.2 硬盘分区的类别1.3 硬盘分区的方式1.3.1 MBR分区1.3.2 GPT分区 1.4 硬盘分区的意义1.4.1 分区的作用1.4.2 分区的缺点 二、如何建立分区2.1 分区命令2.1.1 fdisk命令2.1.2 gdisk命令 2.2 建立分区2.2.1 建立MBR分区建立主分区建立扩展…

电脑如何在网页上下载视频 浏览器如何下载网页视频

对于现代职场人士而言&#xff0c;在日常生活中难免需要下载各种短视频&#xff0c;IDM下载加速器可以轻松获取抖音、快手等平台的无水印短视频文件。 Internet Download Manager&#xff0c;简称IDM。功能强大的网络下载器。您不需要多余的操作&#xff0c;IDM 能捕获您的下载…

实战

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 实战一&#xff1a;模拟支付宝蚂蚁森林的能量产生过程 支付宝的蚂蚁森林通过日常的走步、生活缴费、线下支付、网络购票、共享单车等低碳、环保行为…

行为设计模式之策略模式

文章目录 概述原理结构图 代码实现小结 概述 策略模式(strategy pattern)的原始定义是&#xff1a;定义一系列算法&#xff0c;将每一个算法封装起来&#xff0c;并使它们可以相互替换。策略模式让算法可以独立于使用它的客户端而变化。 在软件开发中也会遇到相似的情况&…

【Lexus.4】Executive Sedan——Dismantling Follow-up

文章目录 【碰撞测试】前后防撞钢梁偏置碰撞A/B/C柱&#xff0c;边梁抗拉、屈服强度 【底盘】平整度护板&#xff08;发动机&#xff0c;底盘&#xff09;前副车架结构前悬架形式后悬架形式与材质簧下质量 【发动机】【轮上马力】【零部件供应商】 来自2021《懂车大爆炸》——是…

操作系统课程实验1-进程调度模拟实验

操作系统课程实验1-进程调度模拟实验 一、实验介绍 1.1 实验目的 本实验模拟在单处理机环境下的处理机调度&#xff0c;帮助理解进程调度的概念&#xff0c;深入了解进程控制块的功能&#xff0c;以及进程的创建、撤销和进程各个状态间的转换过程。 1.2 实验内容 进程调度算…

md是什么?如何打开md类型的文件?假如使用Typora打开,如何免费激活Typora?

md是什么&#xff1f;如何打开md类型的文件 前言一、md是什么简介常见打开md类型文件的方法使用文本编辑器使用专用Markdown编辑器使用在线Markdown编辑器在浏览器中安装插件打开 二、下载安装Typora三、免费激活Typora激活Typora关闭软件每次启动时的已激活弹窗去除软件左下角…

动手学深度学习4.6 暂退法-笔记练习(PyTorch)

以下内容为结合李沐老师的课程和教材补充的学习笔记&#xff0c;以及对课后练习的一些思考&#xff0c;自留回顾&#xff0c;也供同学之人交流参考。 本节课程地址&#xff1a;丢弃法_哔哩哔哩_bilibili 本节教材地址&#xff1a;4.6. 暂退法&#xff08;Dropout&#xff09;…

NDIS驱动程序堆栈

NDIS 6.0 引入了暂停和重启驱动程序堆栈的功能。 若要支持 NDIS 6.0 提供的堆栈管理功能&#xff0c;必须重写旧版驱动程序。 NDIS 6.0 还引入了 NDIS Filter驱动程序。 Filter驱动程序可以监视和修改协议驱动程序与微型端口驱动程序之间的交互。 与 NDIS 5 相比&#xff0c;F…