leetcode每日一题:309. 最佳买卖股票时机含冷冻期

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

给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 。​

设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):

  • 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
  • 卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。

示例:

输入: [1,2,3,0,2]
输出: 3 
解释: 对应的交易状态为: [买入, 卖出, 冷冻期, 买入, 卖出]

来源:力扣(LeetCode)
参考链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown

思路

由于后面的利润是基于前面的操作的,比如,你今天卖了,明天就是冷冻期,不能进行操作。或者,今天买了,明天才能卖或者什么都不操作,但肯定不能再买了。所以这是一个状态转移的过程,要使用动态规划解决。考虑买入利润为负,卖出利润为正,第i天的利润为f[i]

根据是否拥有股票和是否处于冷冻期可以将一天结束的状态分为三种情况,本来是2×2种,但是,买入股票即拥有股票,必不存在冷冻期。而没有股票可能是因为卖出进入冷冻期,前一天是没股票,今天也没买入就不进入冷冻期。

第一种

  • 持有一支股票,当天利润为f[i][0];

第二种

  • 没有持有股票,在冷冻期,当天利润为f[i][1];

第三种

  • 没有持有股票,没在冷冻期,当天利润为f[i][2];

如果处于第一种情况,可能是前一天拥有股票,今天没有操作。或者,前一天没有股票,而且没进入冷冻期,今天买入,所以状态转移方程为

f[i][0] = max(f[i-1][0],f[i-1][2]-prices[i]);

如果处于第二种情况,那就是今天卖出了,前一天的必须有一支股票,状态转移方程为

f[i][1] = f[i-1][0] + prices[i];

如果处于第三种情况,那可能是前一天处于冷冻期,或者前一天也处于第三种情况。状态转移方程为

f[i][2] = max(f[i-1][1],f[i-1][2]);

最后,最大利润就是三种情况中的最大值,但是最后一天还拥有一支股票,显然不会是最大值,所以最后结果为

max(f[i][1],f[i][2]);

仔细一看,由于前一天的状态使用过之后,就没有保存的必要,所以可以使用迭代更新的方法节省空间。代码如下:

代码

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n = prices.size();
        if (n == 0)
            return 0;
        int f0 = -prices[0];
        int f1 = 0;
        int f2 = 0;
        for (int i = 1;i < n;i++){
            int new0 = max(f0,f2-prices[i]);
            int new1 = f0 + prices[i];
            int new2 = max(f1,f2);
            f0 = new0;
            f1 = new1;
            f2 = new2;
        }
        return max(f1,f2);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值