跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

多状态动态规划:买卖股票最佳时机系列问题解析

通过动态规划解决三道经典的买卖股票问题。首先分析含冷冻期的情况,定义买入、卖出、冷冻期三种状态及转移方程;其次引入手续费场景,调整卖出状态的利润计算;最后处理最多两次交易限制,增加交易次数维度。代码均使用 C++ 实现,涵盖状态初始化、循环遍历及结果选取逻辑。

数字游民发布于 2026/3/23更新于 2026/7/521K 浏览
多状态动态规划:买卖股票最佳时机系列问题解析

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

文章配图

分析

使用动态规划解决。

状态表示

由于有「买入」「可交易」「冷冻期」三个状态,因此我们可以选择用三个数组,其中:

  • dp[i][0] 表示:第 i 天结束后,处于「买入」状态,此时的最大利润。
  • dp[i][1] 表示:第 i 天结束后,处于「可交易」状态,此时的最大利润。
  • dp[i][2] 表示:第 i 天结束后,处于「冷冻期」状态,此时的最大利润。

状态转移方程

  1. 处于买入状态的时候,我们现在有股票,此时不能买股票,只能继续持有股票,或者卖出股票;
  2. 处于卖出状态的时候:
    • 如果在冷冻期,不能买入。
    • 如果不在冷冻期,才能买入。

画出状态图

文章配图

根据状态图可以得出:

买入->买入:什么都不干 买入->卖出:买入股票 对应代码:a[i]=max(a[i-1],c[i-1]-prices[i-1]);

卖出->卖出:什么都不干 卖出->冷冻期:卖出股票 对应代码:b[i]=max(b[i-1],a[i-1]+prices[i-1]);

冷冻期->冷冻期:什么都不干 冷冻期->买入:冷冻期结束 对应代码:c[i]=max(c[i-1],b[i-1]);

代码

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n = prices.size();
        vector<int> a(n + 1); // 买入
        vector<int> b(n + 1); // 卖出
        vector<int> c(n + 1); // 冷冻
        
        a[0] = -prices[0];
        for (int i = 1; i <= n; i++) {
            a[i] = max(a[i - 1], c[i - 1] - prices[i - 1]);
            b[i] = max(b[i - 1], a[i - 1] + prices[i - 1]);
            c[i] = max(c[i - 1], b[i - 1]);
        }
        return max(b[n], c[n]); // 从卖出和冷冻期中选出最大值,因为买入状态肯定不是最大值,因为还有股票没有卖出。
    }
};

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

文章配图

分析

使用动态规划解决。与买卖股票的最佳时机含冷冻期问题相似,我们直接画出状态图写状态方程。

状态图

文章配图

买入->买入:什么都不干 买入->卖出:买入股票 对应代码:a[i]=max(a[i-1],c[i-1]-prices[i-1]);

卖出->卖出:什么都不干 卖出->买入:卖出股票并支付手续费 对应代码:b[i]=max(b[i-1],a[i-1]+prices[i-1]-fee);

代码

class Solution {
public:
    int maxProfit(vector<int>& prices, int fee) {
        int n = prices.size();
        vector<int> a(n + 1); // 买入
        vector<int> b(n + 1); // 卖出
        a[0] = -prices[0];
        for (int i = 1; i <= n; i++) {
            a[i] = max(a[i - 1], b[i - 1] - prices[i - 1]);
            b[i] = max(b[i - 1], a[i - 1] + prices[i - 1] - fee);
        }
        return b[n];
    }
};

买卖股票的最佳时机 III

文章配图

状态表示

这里我们选择比较常用的方式,以某个位置为结尾,结合题目要求,定义一个状态表示:由于有「买入」「可交易」两个状态,因此我们可以选择用两个数组。但是这道题里面还有交易次数的限制,因此我们还需要再加上一维,用来表示交易次数。其中:

  • f[i][j] 表示:第 i 天结束后,完成了 j 次交易,处于「买入」状态,此时的最大利润;
  • g[i][j] 表示:第 i 天结束后,完成了 j 次交易,处于「卖出」状态,此时的最大利润。

状态转移方程

A. 对于 f[i][j],我们有两种情况到这个状态:

  1. 在 i - 1 天的时候,交易了 j 次,处于「买入」状态,第 i 天啥也不干即可。此时最大利润为:f[i - 1][j];
  2. 在 i - 1 天的时候,交易了 j 次,处于「卖出」状态,第 i 天的时候把股票买了。此时的最大利润为:g[i - 1][j] - prices[i]。 综上,我们要的是「最大利润」,因此是两者的最大值:f[i][j] = max(f[i - 1][j], g[i - 1][j] - prices[i])。

B. 对于 g[i][j],我们也有两种情况可以到达这个状态:

  1. 在 i - 1 天的时候,交易了 j 次,处于「卖出」状态,第 i 天啥也不干即可。此时的最大利润为:g[i - 1][j];
  2. 在 i - 1 天的时候,交易了 j - 1 次,处于「买入」状态,第 i 天把股票卖了,然后就完成了 j 比交易。此时的最大利润为:f[i - 1][j - 1] + prices[i]。但是这个状态不一定存在,要先判断一下。 综上,我们要的是最大利润,因此状态转移方程为: g[i][j] = g[i - 1][j]; if(j >= 1) g[i][j] = max(g[i][j], f[i - 1][j - 1] + prices[i]);

代码

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

目录

  1. 买卖股票的最佳时机含冷冻期
  2. 分析
  3. 状态表示
  4. 状态转移方程
  5. 画出状态图
  6. 代码
  7. 买卖股票的最佳时机含手续费
  8. 分析
  9. 状态图
  10. 代码
  11. 买卖股票的最佳时机 III
  12. 状态表示
  13. 状态转移方程
  14. 代码
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • AI 产品经理学习路线:从零基础到大模型应用实战指南
  • C++微服务 UserServer 设计与实现
  • 基于YOLO与LLM的Web目标检测及人脸表情识别系统
  • 基于 Web 的高校工会管理系统设计与实现
  • 高精度运算的加减乘除算法详解
  • 9 款 AI 写作工具辅助论文写作指南
  • ComfyUI 黎黎原上咩 7.0 整合包一键部署指南
  • Oracle WebLogic 代理插件未授权 RCE 漏洞检测与分析
  • 手机安全渗透测试新手入门指南
  • VsCode 远程 Copilot 调用 Claude Agent 报“无效请求”:参数配置排查与修复
  • C++ 协程与 Fiber:游戏开发中的异步编程模型应用
  • 35 道常见前端 Vue 面试题解析
  • 昇腾 NPU 部署 CodeLlama 大模型实战指南
  • Qwen3+Qwen Agent 智能体开发实战:接入 MCP 工具
  • C++ 二叉搜索树原理与高效实现
  • 算法实战:寻找数组中心下标与除自身外数组乘积(前缀和技巧)
  • HarmonyOS RcList 组件缩略图、角标与图标系统设计
  • C++ Google Test (gtest) 全面使用指南
  • 大模型基座训练的挑战与难点
  • 大模型 Token 机制与上下文窗口管理实战

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online