最佳买卖股票时机含冷冻期--动态规划

给定一个整数数组prices,其中第 prices[i] 表示第 i 天的股票价格 。

设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票): 卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例 1:

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

输入: prices = [1]
输出: 0

提示:

1 <= prices.length <= 5000
0 <= prices[i] <= 1000

一种常用的方法是将“买入”和“卖出”分开进行考虑:“买入”为负收益,“卖出”为正收益。开始,只有“买入”的权利,只能获得负收益。可以使用动态规划维护在股市中每一天结束后可以获得的“累积最大收益”,并以此进行状态转移。

思路

f [ i ] f[i] f[i] 表示第i天结束之后的“累积最大收益”(从0开始)。我们最多只能同时买入(持有)一支股票,卖出后有冷冻期的限制,因此有三种不同的状态:

  • 目前持有一支股票,对应的“累积最大收益”记为 f [ i ] [ 0 ] f[i][0] f[i][0]
  • 目前不持有任何股票,并且处于冷冻期中,对应的“累积最大收益”记为 f [ i ] [ 1 ] f[i][1] f[i][1]
  • 目前不持有任何股票,并且不处于冷冻期中,对应的“累积最大收益”记为 f [ i ] [ 2 ] f[i][2] f[i][2]

这里的处于冷冻期指的是在第 i 天结束之后的状态。也就是说:如果第 i 天结束之后处于冷冻期,那么第 i+1 天无法买入股票。

第i 天的状态由第 i-1 天状态转移而来,转移方程为:

f [ i ] ] [ 0 ] = m a x ( f [ i − 1 ] [ 0 ] , f [ i − 1 ] [ 2 ] − p r i c e [ i ] ) f[i]][0] = max(f[i-1][0], f[i-1][2] - price[i]) f[i]][0]=max(f[i1][0],f[i1][2]price[i])

f [ i ] [ 1 ] = f [ i − 1 ] [ 0 ] + p r i c e [ i ] f[i][1] = f[i-1][0]+price[i] f[i][1]=f[i1][0]+price[i]

f [ i ] [ 2 ] = m a x ( f [ i − 1 ] [ 1 ] , f [ i − 1 ] [ 2 ] ) f[i][2] = max(f[i-1][1], f[i-1][2]) f[i][2]=max(f[i1][1],f[i1][2])

如果一共有 n 天,答案为:

m a x ( f [ n − 1 ] [ 1 ] , f [ n − 1 ] [ 2 ] ) max(f[n-1][1], f[n-1][2]) max(f[n1][1],f[n1][2])

f [ n − 1 ] [ 0 ] f[n-1][0] f[n1][0] 表示最后还持有股票,显然不符合收益最大。

初始条件为:

f [ 0 ] [ 0 ] = − p r i c e [ 0 ] f [ 0 ] [ 1 ] = 0 f [ 0 ] [ 2 ] = 0 f[0][0]=-price[0] \\ f[0][1]=0 \\f[0][2]=0 f[0][0]=price[0]f[0][1]=0f[0][2]=0

class Solution:
    def maxProfit(self, prices: list) -> int:
        if not prices:
            return 0

        f = [[-prices[0], 0, 0]] + [[0] * 3 for i in range(len(prices)-1)]
        for i in range(1, len(prices)):
            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])

        return max(f[-1][1],f[-1][2])


if __name__ == '__main__':
    s = Solution()
    print(s.maxProfit([1,2,3,0,2]))

参考

https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-with-cooldown/solution/zui-jia-mai-mai-gu-piao-shi-ji-han-leng-dong-qi-4/

你可能感兴趣的:(LeetCode,动态规划,算法)