【題目描述】
Say you have an array for which the?i?th element is the price of a given stock on day?i.
Design an algorithm to find the maximum profit. You may complete at most?k transactions.
?Notice:You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again).
假設你有一個數組,它的第i個元素是一支給定的股票在第i天的價格。
設計一個算法來找到最大的利潤。你最多可以完成?k?筆交易。
【注】你不可以同時參與多筆交易(你必須在再次購買前出售掉之前的股票)
【題目鏈接】
www.lintcode.com/en/problem/best-time-to-buy-and-sell-stock-iv/
【題目解析】
下面的解法主要是能把兩次的限制推廣到k次交易:
這道題是Best Time to Buy and Sell Stock的擴展,現在最多可以進行兩次交易。所以仍然使用動態規劃來完成,事實上可以解決非常通用的情況,也就是最多進行k次交易的情況。 這里我們先解釋最多可以進行k次交易的算法,然后最多進行兩次我們只需要把k取成2即可。我們還是使用“局部最優和全局最優解法”。我們維護兩種量,一個是當前到達第i天可以最多進行j次交易,最好的利潤是多少(global[i][j]),另一個是當前到達第i天,最多可進行j次交易,并且最后一次交易在當天賣出的最好的利潤是多少(local[i][j])。下面我們來看遞推式,全局的比較簡單,
global[i][j]=max(local[i][j],global[i-1][j]),
也就是去當前局部最好的,和過往全局最好的中大的那個(因為最后一次交易如果包含當前天一定在局部最好的里面,否則一定在過往全局最優的里面)。
全局(到達第i天進行j次交易的最大收益) = max{局部(在第i天交易后,恰好滿足j次交易),全局(到達第i-1天時已經滿足j次交易)}
對于局部變量的維護,遞推式是
local[i][j]=max(global[i-1][j-1]+max(diff,0),local[i-1][j]+diff),
也就是看兩個量,第一個是全局到i-1天進行j-1次交易,然后加上今天的交易,如果今天是賺錢的話(也就是前面只要j-1次交易,最后一次交易取當前天),第二個量則是取local第i-1天j次交易,然后加上今天的差值(這里因為local[i-1][j]比如包含第i-1天賣出的交易,所以現在變成第i天賣出,并不會增加交易次數,而且這里無論diff是不是大于0都一定要加上,因為否則就不滿足local[i][j]必須在最后一天賣出的條件了)。
局部(在第i天交易后,總共交易了j次) = max{情況2,情況1}
情況1:在第i-1天時,恰好已經交易了j次(local[i-1][j]),那么如果i-1天到i天再交易一次:即在第i-1天買入,第i天賣出(diff),則這不并不會增加交易次數!【例如我在第一天買入,第二天賣出;然后第二天又買入,第三天再賣出的行為 和 第一天買入,第三天賣出 的效果是一樣的,其實只進行了一次交易!因為有連續性】 情況2:第i-1天后,共交易了j-1次(global[i-1][j-1]),因此為了滿足“第i天過后共進行了j次交易,且第i天必須進行交易”的條件:我們可以選擇1:在第i-1天買入,然后再第i天賣出(diff),或者選擇在第i天買入,然后同樣在第i天賣出(收益為0)。
上面的算法中對于天數需要一次掃描,而每次要對交易次數進行遞推式求解,所以時間復雜度是O(n*k),如果是最多進行兩次交易,那么復雜度還是O(n)。空間上只需要維護當天數據皆可以,所以是O(k),當k=2,則是O(1)。
【參考答案】
www.jiuzhang.com/solutions/best-time-to-buy-and-sell-stock-iv/