而买卖股票这个题目,是典型的根据这一天分类出的所有状态都和前一天的所有状态之间的关系推导出状态转移方程
根据第 i 天的交易情况,可以分为以下几种状态
s1: 第 i 天结束处于持有股票状态获得的最大利润
s2: 第 i 天结束处于未持有股票状态, 且不是冷冻期获得的最大利润
s3: 第 i 天结束处于未持有股票状态, 且是冷冻期获得的最大利润
那么就可以画出如下状态机,其中状态之间的连线表示的含义如下,以 s1 -> s3 为例
s1 -> s3表示从第 i - 1 天的 s1到 第 i 天的 s3
此时值得说明的有三个状态变换是不存在的
s1->s2 是不存在的,这是因为当第i - 1天结束后为持有股票的状态时,只要在第 i 天卖出股票,就会直接进入冷冻期(换句话说,第 i 天卖出股票之后,将直接将状态变成s3)
s2->s3是不存在的,这是因为当i - 1天结束后为非冷冻期的非持有股票状态时,不能在第 i 天卖出股票来进入冷冻期
s3 -> s1是不存在的,这是因为当i - 1天结束后是冷冻期(换句话说,第i - 1天进行了卖出股票的操作),说明第 i 天不能进行交易(而且在第i 天冷冻完毕后,将进入s2)
初始化没有什么需要特别考虑的东西,其代码如下:
class Solution {
public:int maxProfit(vector<int>& prices) {int n = prices.size();// 第 i 天结束处于持有股票状态获得的最大利润vector<int> f(n);f[0] = -1 * prices[0];// 第 i 天结束处于未持有股票状态, 且不是冷冻期获得的最大利润vector<int> g(n);// 第 i 天结束处于未持有股票状态, 且是冷冻期获得的最大利润vector<int> h(n, -1 * 0x3fffff);for(int i = 1; i < n; ++i){f[i] = max(f[i - 1], g[i - 1] - prices[i]);g[i] = max(g[i - 1], h[i - 1]);h[i] = f[i - 1] + prices[i];}return max({f[n - 1], g[n - 1], h[n - 1]});}
};