动态规划问题 -- 多状态模型(买股票的最佳时机II)

发布于:2025-05-16 ⋅ 阅读:(20) ⋅ 点赞:(0)

动态规划分析问题五步曲

不清楚动态规划分析问题是哪关键的五步的少年们可以移步到
链接: 动态规划算法基础
这篇文章非常详细的介绍了动态规划算法是如何分析和解决问题的

题目概述

链接: 买股票的最佳时机II
在这里插入图片描述

  1. 状态表示(题目要求+自己的经验)
    本题状态:分析第i个位置,发现在第i个位置我们可以处于可买入或可卖出状态
    所以本题应该有两个状态表示
    buy[i] : 表示第i个位置为可买入状态(即在i位置时没持有股票)可获得的最大利润
    sell[i] : 表示第i个位置为可出售状态(即在i位置时持有股票)可获得的最大利润

利用状态机推导状态转移方程式

再推导状态转移方程式之前,不妨列出所有状态之间的转换关系
这些状态之间的转换关系,就被称之为状态机

本题 可买入和可卖出状态的状态机如下

在这里插入图片描述

  1. 状态转移方程推导
    对i位置进行分类讨论,再配合状态机的使用
    当i位置为可买入状态,第i-1个位置可能为可买入状态或可卖出状态
    当i位置为可卖出状态,第i-1个位置可能为可买入状态或可卖出状态
    (要注意从可买入状态可卖出状态可卖出状态可买入状态的转换)
    在这里插入图片描述
  1. 初始化(防止越界+结合状态表示初始化)
    根据状态转移方程,当i = 0时会发生越界
    根据状态表示 :
    buy[0] : 要使得第一个位置为可买入状态,那么不买入股票就行 buy[0] = 0;
    sell[0] : 要使得第一个位置为可卖出状态,那么一定要买入第一份股票 sell[0] = 0-prices[0] ;
  1. 填表顺序(分析要填i位置前一个依赖状态的位置)
    本题两个dp表显然都是从左到右填表
  1. 返回值(由题目要求来)
    最后一个位置处于可卖出状态,一定不是最大利润
    buy[m-1] > sell[m-1] 恒成立,所以最后返回的是 buy[m-1] ;

代码编写

有了动态规划五步曲我们就可以写出非常优雅的代码了

 int maxProfit(vector<int>& prices) {
        int n = prices.size();
        if(n == 0) return 0;

        vector<int> buy(n);
        auto sell = buy;
        auto ice = buy;

        sell[0] -= prices[0];
        for(int i = 1 ; i < n ; i++)
        {
            buy[i] = max(buy[i-1],ice[i-1]);
            sell[i] = max(buy[i-1]-prices[i],sell[i-1]);
            ice[i] = sell[i-1] + prices[i];
        }

        return max(ice[n-1],buy[n-1]);
    }
      

少年,今天你又进步了一点点哟,明天继续加油吧
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到