Algorithm 了解简明的DP解决方案,以便在最佳时间买卖股票IV

Algorithm 了解简明的DP解决方案,以便在最佳时间买卖股票IV,algorithm,dynamic-programming,Algorithm,Dynamic Programming,问题是著名的(或在类似的其他情况下),最好买卖股票,最多有k笔交易。 以下是问题的屏幕截图: 我试图理解这个DP解决方案。可以忽略大k的第一部分。我不明白dp部分为什么会起作用 class Solution(object): def maxProfit(self, k, prices): """ :type k: int :type prices: List[int] :rtype: int

问题是著名的(或在类似的其他情况下),最好买卖股票,最多有k笔交易。 以下是问题的屏幕截图:

我试图理解这个DP解决方案。可以忽略大k的第一部分。我不明白dp部分为什么会起作用

class Solution(object):
    def maxProfit(self, k, prices):
        """
        :type k: int
        :type prices: List[int]
        :rtype: int
        """
        # for large k greedy approach (ignore this part for large k)
        if k >= len(prices) / 2:
            profit = 0
            for i in range(1, len(prices)):
                profit += max(0, prices[i] - prices[i-1])
            return profit

#       Don't understand this part 
        dp = [[0]*2 for i in range(k+1)]
                             
        for i in reversed(range(len(prices))):
            for j in range (1, k+1):
                dp[j][True] = max(dp[j][True], -prices[i]+dp[j][False])
                dp[j][False] = max(dp[j][False], prices[i]+dp[j-1][True])
            
        return dp[k][True]        
我能够驱动一个类似的解决方案,但它使用两行(dp和dp2),而不是一行(上面的解决方案中的dp)。在我看来,解决方案似乎正在覆盖自身的值,这对于这个解决方案来说是不正确的。然而,答案是有效的,并通过leetcode。

让我们用文字来表达:

for i in reversed(range(len(prices))):
在考虑了以后的价格后,我们已经提前知道了未来的价格

  for j in range (1, k+1):
对于将此价格视为
k
两种价格交易之一的每种可能性

    dp[j][True] = max(dp[j][True], -prices[i]+dp[j][False])

如果我们认为这可能是一个购买——因为我们在时间上倒退,一个购买意味着一个完整的交易——我们选择了最好的(1),已经考虑了<代码> j/Cuth>第三次购买(<代码> dp[j] [Trime] <代码>)或(2)减去此价格作为购买,并添加我们已经得到的最佳结果,包括第次销售(

-prices[i]+dp[j][False]

否则,我们可以将其视为一种销售(我们向后交易的前半部),因此我们选择了(1)已经考虑过的<代码> >代码>代码>销售(<代码> dp[j](false)<代码>),或者(2)我们将此价格作为销售,并添加到迄今为止对于第一个代码>(J - 1)的最好结果。已完成的交易(

价格[i]+dp[j-1][True]

请注意,第一个
dp[j][False]
指的是
j
th“半交易”,如果您愿意的话,因为我们在时间上是倒退的,这将在较早的迭代中设定在较后的价格上。然后,我们可能会将此价格作为第次销售来考虑

    dp[j][False] = max(dp[j][False], prices[i]+dp[j-1][True])