Top 100 Linked Question 修炼------第309题

本文深入探讨了股票交易策略中的“最佳时机”问题,特别是在考虑到冷冻期约束的情况下。通过动态规划的方法,详细分析了如何在给定股票价格序列中找到最大收益的买卖策略,包括买入、卖出和冷冻期的状态转移过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

309. Best Time to Buy and Sell Stock with Cooldown

题目链接

题目解释

假设你有一个数组,数组里面的第i个元素是第i天的股票的价格。

设计一个算法找到最大的收益,你可以完成任意次数的交易(即可以买卖一个股票多次),但是存在如下的限制:

  • 你不能一次进行多个交易(比如:你在买股票之前必须卖掉股票)
  • 在卖了你的股票之后,你在卖股票的下一天不能买股票(即存在冷冻期)

Example:

Input: [1,2,3,0,2]
Output: 3 
Explanation: transactions = [buy, sell, cooldown, buy, sell]

题目分析

本题中存在一定的状态转移过程,主要是条件的约束过程,存在这样的解答的话我们可以去画出状态转移图:

图片参考地址:https://blog.csdn.net/zjuPeco/article/details/76468185

这里我们引入了三个状态分别为买,休息以及卖,我们需要引入三个数组,分别为buy,rest,sell,其中:

buy[i]表示在第i天之前最后一个操作是买(并不一定需要第i天去买),此时的最大收益。

sell[i]表示在第i天之前最后一个操作是卖,此时的最大收益。

rest[i]表示在第i天之前最后一个操作是冷冻期,此时的最大收益。

我们可以从这个状态转移图,得到每个数组之间的状态转移方程:

# 第i天之前最后一个操作是买时,获得的最大利润为第i-1天的价格减去第i天买入的价格与第i-1天买入最大值
buy[i]  = max(rest[i-1] - price, buy[i-1]) 
sell[i] = max(buy[i-1] + price, sell[i-1])
rest[i] = max(sell[i-1], buy[i-1], rest[i-1])

上述递推式很好的表示了在买之前有冷冻期,买之前要卖掉之前的股票。一个小技巧是如何保证[buy, rest, buy]的情况不会出现,这是由于buy[i] <= rest[i], 即rest[i] = max(sell[i-1], rest[i-1]),这保证了[buy, rest, buy]不会出现。

class Solution:
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        if not prices:
            return 0
        len_prices = len(prices)
        # 初始化三个数组,确定三个数组的含义
        buy, sell, cooldown = [0]*len_prices, [0]*len_prices, [0]*len_prices
        # 初始化,其中第1天是可以买入的
        buy[0] = -prices[0]
        for i in range(1, len_prices):
            # 如果第i天是冷却期,那么这天的收益和前一天卖出股票的收益相同
            cooldown[i] = sell[i-1]
            # 如果第i天卖出股票,那么无非是i-1之前就持有股票,所以index:i-1天也可以卖出,或者另一种情况就是index:i-1当天买入了股票。
            sell[i] = max(sell[i-1], buy[i-1] + prices[i])
            # 如果第i天买入股票,无非是i-1之前就不持有股票,我们要考虑哪天买,所以i-1也可以买入(第i-1天不持有股票),或者另一种可能就是i-1天是冷冻期。
            buy[i] = max(buy[i-1], cooldown[i-1] - prices[i])

        return max(sell[len_prices - 1], cooldown[len_prices - 1])

PS:后序在整理的时候还会进行一定的优化,并且将所有的股票问题全都写出来。

Reference

https://www.cnblogs.com/grandyang/p/4997417.html

总结

2019/6/11:多个状态之间的转移还是比较困难的.....

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值