動態規劃之股票問題123

Shunzuo Wu發表於2020-12-17

問題描述:

給定一個陣列,它的第 i 個元素是一支給定的股票在第 i 天的價格。

設計一個演算法來計算你所能獲取的最大利潤。你最多可以完成 兩筆 交易。

注意: 你不能同時參與多筆交易(你必須在再次購買前出售掉之前的股票)。

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。

 示例:

輸入: [3,3,5,0,0,3,1,4]
輸出: 6
解釋: 在第 4 天(股票價格 = 0)的時候買入,在第 6 天(股票價格 = 3)的時候賣出,這筆交易所能獲得利潤 = 3-0 = 3 。
     隨後,在第 7 天(股票價格 = 1)的時候買入,在第 8 天 (股票價格 = 4)的時候賣出,這筆交易所能獲得利潤 = 4-1 = 3 

分析:

又加了一個限制,只能購買兩次,這已然難不倒我們,我們只需要把第 i 天,第 j 次交易完成後的收益記錄下來了。

設dp0[m][n],為第 i 天, 第 j 次交易,且手中沒有沒有股票(賣出)

設dp1[m][n],為di i 天,第 j 次交易,且手中有股票(買入)

這裡第 i 天賣出股票的的狀態不僅和 第 i - 1天的買入有關係,還和 j - 1 次交易有關係。

第 i 天買入的狀態只和上一次交易完成時的狀態有關,上一次交易完成了,就不會干擾到新的交易。

得出dp方程

dp0[i][j] = max(dp0[i][j], dp1[i-1][j-1] + price[i])

dp1[i][j] = max(dp1[i][j], dp0[i-1][j] - price[i])

上程式碼:

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        # dp[i][j]  i 天,j次
        # dp0  手頭沒有股票
        # dp1  手頭有股票
        dp0 = [[0]*3 for _ in range(len(prices))]
        dp1 = [[0]*3 for _ in range(len(prices))]
        
        for j in range(3):
            dp1[0][i] = -prices[0]
        for i in range(1, len(prices)):
            dp1[i][0] = max(dp1[i-1][0], -prices[i])
            for j in range(1,3):
                dp0[i][j] = max(dp0[i-1][j], dp1[i-1][j-1] + prices[i])
                dp1[i][j] = max(dp1[i-1][j], dp0[i-1][j] - prices[i])
        for i in range(len(dp0)):
            print(dp0[i])
        return dp0[-1][-1]

說明:一次交易都沒完成的時候,也就是需要買入股票,所以需要初始化dp1[i][0] = max(dp1[i-1][0], -prices[i])

 

 

 

 

相關文章