Question
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete at most two transactions.
Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
Solution
解题的第一步是首先必须意识到,因为限制了交易次数,现在这是一道DP问题而不是简单的Array问题。因为显而易见的是第一次交易sell的时间会完全影响第二次交易buy的时间。
那么状态转移图如下:
图中用红笔圈出的箭头在第一次画的时候是没有的。因为我第一次思考的时候没有完全使用DP的思维,所有自循环的箭头标的都是“wait”而不是“loop”。我认为每一次循环,算法是尝试计算一个值和之前的值比较,如果计算出的值不满足替换条件则放弃该次计算等待下一轮循环。所以我认为当找到最大的
buy2
b
u
y
2
状态之后,只需要找到唯一最大的
sell2
s
e
l
l
2
状态即可,所以
sell2
s
e
l
l
2
状态是没有自循环箭头的。显然这样的状态转移图无法写出合适的状态转移方程。
然而实际的DP思维应该是每一轮循环都确实先进行了计算,之后再进行比较,不满足替代条件则抛弃本轮的计算值。即是,在本题中,每一次循环都确实产生了一个新的
sell2
s
e
l
l
2
状态并且需要和上一次循环的值进行对比,所以自循环箭头是必要的,且箭头的标识也不应该是‘wait’而应该是‘loop’。我在之前的一道题中也犯了相似的错误,只是当时对结果没有产生影响。
澄清这一点之后,就很容易能得到如下代码:
class Solution:
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
buy1,sell1,buy2,sell2 = float('-inf'),0,float('-inf'),0
for p in prices:
sell2 = max(buy2+p,sell2)
buy2 = max(sell1-p,buy2)
sell1 = max(buy1+p,sell1)
buy1 = max(buy1,-p)
return sell2