在“股票市场交易策略优化”这道题目中,目标是帮助小R通过买卖股票来最大化收益。小R可以多次买卖股票,但需要遵守一个规则:在每次买入股票之前必须卖出之前的股票,而且每次卖出股票后有一天的冷冻期。在冷冻期内小R不能购买股票。
解题思路
-
动态规划状态设计:
-
我意识到,可以通过动态规划来解决这个问题,因为每一天的操作和收益都与前一天的状态密切相关。
-
为了实现这个思路,我将每一天的状态分为三种情况:
- 持有股票(hold) :当天结束时持有一只股票的状态。
- 卖出股票(sell) :当天卖出股票的状态,这意味着可以获得收益。
- 冷冻期(cooldown) :当天是冷冻期,不能买入股票,也没有卖出股票。
-
-
状态转移方程:
-
通过观察,我得出每个状态的状态转移方程:
-
hold[i] :表示在第
i天结束时持有一只股票的最大收益。可以从以下两种情况得到:- 我在前一天已经持有股票,今天继续保持不动:
hold[i] = hold[i-1] - 今天我选择买入股票,这样要求昨天是冷冻期(没有持股):
hold[i] = cooldown[i-1] - stocks[i] - 因此,
hold[i] = max(hold[i-1], cooldown[i-1] - stocks[i])
- 我在前一天已经持有股票,今天继续保持不动:
-
sell[i] :表示在第
i天结束时卖出股票的最大收益。只能从前一天持有股票的状态转移而来:sell[i] = hold[i-1] + stocks[i] -
cooldown[i] :表示第
i天是冷冻期的最大收益。可以从以下两种情况得到:- 前一天已经是冷冻期,那么今天继续冷冻:
cooldown[i] = cooldown[i-1] - 昨天卖出了股票,今天进入冷冻期:
cooldown[i] = sell[i-1] - 因此,
cooldown[i] = max(cooldown[i-1], sell[i-1])
- 前一天已经是冷冻期,那么今天继续冷冻:
-
-
-
初始条件:
-
在第0天:
hold[0]初始化为-stocks[0],因为如果在第0天买入股票,收益就是负的股票价格。sell[0]和cooldown[0]初始化为0,因为没有卖出或者冷冻的操作发生。
-
-
最终结果:
- 最后一天可以获得的最大收益是
sell或cooldown的状态,不能是hold,因为最后一天持有股票意味着没有卖出,这不符合收益最大化的目标。
- 最后一天可以获得的最大收益是
知识点总结
- 动态规划的状态转移:我根据题目需求,将问题分解为状态转移。通过分析“持有”、“卖出”和“冷冻期”这三种状态,得到了每天的最优收益。
- DP的空间优化:虽然在这个解法中,每个状态使用一个数组来存储每天的收益,但实际上可以进一步优化空间,因为我们只需要前一天的状态来计算今天的状态。这样可以将空间复杂度从
O(n)优化为O(1)。 - 股票交易中的冷冻期限制:这是题目中一个重要的规则。为了实现这一要求,我设计了
cooldown状态,并确保hold状态在冷冻期之后才能进行操作。
代码实现
def solution(stocks):
if not stocks:
return 0
n = len(stocks)
hold = [0] * n
sell = [0] * n
cooldown = [0] * n
hold[0] = -stocks[0]
sell[0] = 0
cooldown[0] = 0
for i in range(1, n):
hold[i] = max(hold[i - 1], cooldown[i - 1] - stocks[i])
sell[i] = hold[i - 1] + stocks[i]
cooldown[i] = max(cooldown[i - 1], sell[i - 1])
return max(sell[n - 1], cooldown[n - 1])
总结
在这道题目中,我通过设计三种动态规划状态来逐步求解,确保在每一个步骤中都满足题目的交易规则和冷冻期限制。最终的解法不仅计算准确,还通过对DP状态的优化保持了时间效率,使得代码在大规模输入下依然高效。这种方法不仅在股票交易问题中常用,还可以用于其他类似的动态规划问题。