给定一个整数数组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]=max(f[i−1][0],f[i−1][2]−price[i])f[i]][0] = max(f[i-1][0], f[i-1][2] - price[i])f[i]][0]=max(f[i−1][0],f[i−1][2]−price[i])
f[i][1]=f[i−1][0]+price[i]f[i][1] = f[i-1][0]+price[i]f[i][1]=f[i−1][0]+price[i]
f[i][2]=max(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[i−1][1],f[i−1][2])
如果一共有 n 天,答案为:
max(f[n−1][1],f[n−1][2])max(f[n-1][1], f[n-1][2])max(f[n−1][1],f[n−1][2])
f[n−1][0]f[n-1][0]f[n−1][0] 表示最后还持有股票,显然不符合收益最大。
初始条件为:
f[0][0]=−price[0]f[0][1]=0f[0][2]=0f[0][0]=-price[0] \\ f[0][1]=0 \\f[0][2]=0f[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/
博客围绕含冷冻期的股票交易问题,设计算法计算最大利润。可将“买入”“卖出”分开考虑,用动态规划维护每天结束后的“累积最大收益”。定义三种状态,给出状态转移方程和初始条件,最终得出最大利润的计算方法。
752

被折叠的 条评论
为什么被折叠?



