动态规划-股票交易

买卖股票最佳时机

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        # 甲:这n天怎样买股票赚的多-------------------------------------
        n = len(prices)

        # 乙:dp[i]代表第i天-------------------------------------------
        # 乙:dp[i][0]代表第i天过后手上有股票时的最大收益
        # 乙:总之,今天过后我必有股票在手上,要么之前买的,要么今天买的
        # 乙:dp[i][1]代表第i天过后手上无股票时的最大收益
        # 乙:总之,今天过后我手上空空如也,要么本来就没有,有我也给卖了
        dp = [[0, 0] for _ in range(n)]

        # 乙: 今天是第一天---------------------------------------------
        # 乙: 保证必须有股票是吧,prices[0]块钱拿去,今天股票我买了
        # 乙: 保证没有股票,啥都不干就好了
        dp[0] = [-prices[0], 0]

        # 旁白: 时间一天天过去
        for i in range(1, n):
            # 甲: 今天是第i天,如果我一定要保证自己有股票,该怎么操作------
            # 乙: dp[i-1][0] 今天的股票太贵了,买之前的股票更划算
            # 乙: - prices[i] 今天的股票更便宜,我买了,prices[i]块钱拿去
            dp[i][0] = max(dp[i-1][0], - prices[i])

            # 甲: 今天是第i天,如果我一定要保证自己没有股票,该怎么操作------
            # 乙: dp[i-1][1] 今天股市不行,还是之前卖更划算
            # 乙: + prices[i] + dp[i-1][0] 今天的行情不错,股票卖掉,血赚prices[i]块钱,
            # dp[i-1][0]是我用低价买入花的钱
            dp[i][1] = max(dp[i-1][1], + prices[i] + dp[i-1][0])

        return dp[-1][-1]
无注释代码如下


class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        dp = [[0, 0] for _ in range(n)]
        dp[0] = [-prices[0], 0]
        for i in range(1, n):
            dp[i][0] = max(dp[i-1][0], - prices[i])
            dp[i][1] = max(dp[i-1][1], + prices[i] + dp[i-1][0])
        return dp[-1][-1]

买卖股票最佳时机2

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        # 甲:这n天怎样买股票赚的多-------------------------------------
        n = len(prices)

        # 乙:dp[i]代表第i天-------------------------------------------
        # 乙:dp[i][0]代表第i天过后手上有股票时的最大收益
        # 乙:总之,今天过后我必有股票在手上,要么之前买的,要么今天买的
        # 乙:dp[i][1]代表第i天过后手上无股票时的最大收益
        # 乙:总之,今天过后我手上空空如也,要么本来就没有,有我也给卖了
        dp = [[0, 0] for _ in range(n)]

        # 乙: 今天是第一天---------------------------------------------
        # 乙: 保证必须有股票是吧,prices[0]块钱拿去,今天股票我买了
        # 乙: 保证没有股票,啥都不干就好了
        dp[0] = [-prices[0], 0]

        # 旁白: 时间一天天过去
        for i in range(1, n):
            # 甲: 今天是第i天,如果我一定要保证自己有股票,该怎么操作------
            # 乙: dp[i-1][0] 今天的股票太贵了,买之前的股票更划算
            # 乙: - prices[i] 今天的股票更便宜,我买了,prices[i]块钱拿去
            # dp[i-1][1]是我之前卖股票赚的钱
            dp[i][0] = max(dp[i-1][0], - prices[i] + dp[i-1][1])

            # 甲: 今天是第i天,如果我一定要保证自己没有股票,该怎么操作------
            # 乙: dp[i-1][1] 今天股市不行,还是之前卖更划算
            # 乙: + prices[i] + dp[i-1][0] 今天的行情不错,股票卖掉,血赚prices[i]块钱,
            # dp[i-1][0]是我用低价买入花的钱
            dp[i][1] = max(dp[i-1][1], + prices[i] + dp[i-1][0])

        return dp[-1][-1]
无注释代码如下


class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        dp = [[0,0] for _ in range(n)]
        dp[0] = [-prices[0], 0]
        for i in range(1, n):
            dp[i][0] = max(dp[i-1][0], - prices[i] + dp[i-1][1])
            dp[i][1] = max(dp[i-1][1], + prices[i] + dp[i-1][0])
        return dp[-1][-1]

买卖股票最佳时机3

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        # 甲:这n天怎样买股票赚的多-------------------------------------
        n = len(prices)

        # 乙:dp[i]代表第i天-------------------------------------------
        # 乙:dp[i][0]代表第i天过后第一次买股票时的最大收益
        # 乙:总之,今天过后我必有股票在手上,要么之前买的,要么今天买的
        # 乙:dp[i][1]代表第i天过后第一次卖股票时的最大收益
        # 乙:总之,今天过后我手上空空如也,要么本来就没有,有我也给卖了
        # 乙:dp[i][2]代表第i天过后第二次买股票时的最大收益
        # 乙:dp[i][3]代表第i天过后第二次卖股票时的最大收益
        dp = [[0,0,0,0] for _ in range(n)]

        # 乙: 今天是第一天---------------------------------------------
        # 乙: 第一次买股票是吧,prices[0]块钱拿去,今天股票我买了
        # 乙: 第一次卖股票是吧,prices[0]块钱买来又卖掉,血赚0元
        # 乙: 第二次买,我买了又卖掉又买回来,花费prices[0]块钱
        # 乙: 第二次买,我买了又卖掉又买回来又卖掉,哎,就是玩
        # 注: 在同一天内反复买卖是不影响最终结果的,因为反正都是0
        dp[0]=[-prices[0],0,-prices[0],0]

        # 旁白: 时间一天天过去
        for i in range(1, n):
            # 甲: 今天是第i天,如果我第一次买股票,该怎么操作------
            # 乙: dp[i-1][0] 今天的股票太贵了,买之前的股票更划算
            # 乙: - prices[i] 今天的股票更便宜,我买了,prices[i]块钱拿去
            dp[i][0] = max(dp[i-1][0], -prices[i])

            # 甲: 今天是第i天,如果我第一次卖股票,该怎么操作------
            # 乙: dp[i-1][1] 今天股市不行,还是之前卖更划算
            # 乙: + prices[i] + dp[i-1][0] 今天的行情不错,股票卖掉,血赚prices[i]块钱,
            # dp[i-1][0]是我用低价买入花的钱
            dp[i][1] = max(dp[i-1][1], + prices[i] + dp[i-1][0])

            # 甲: 今天是第i天,如果我第二次买股票,该怎么操作------
            # 乙: dp[i-1][0] 今天的股票太贵了,买之前的股票更划算
            # 乙: - prices[i] 今天的股票更便宜,我买了,prices[i]块钱拿去
            # dp[i-1][1]是我第一次卖股票赚的钱
            dp[i][2] = max(dp[i-1][2], - prices[i] + dp[i-1][1])

            # 甲: 今天是第i天,如果我第一次卖股票,该怎么操作------
            # 乙: dp[i-1][1] 今天股市不行,还是之前卖更划算
            # 乙: + prices[i] + dp[i-1][0] 今天的行情不错,股票卖掉,血赚prices[i]块钱,
            # dp[i-1][2]是我第二次买完股票后的最大收益
            dp[i][3] = max(dp[i-1][3], + prices[i] + dp[i-1][2])

        return dp[-1][-1]
无注释代码如下


class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        dp = [[0,0,0,0] for _ in range(n)]
        dp[0]=[-prices[0],0,-prices[0],0]
        for i in range(1,n):
            dp[i][0] = max(dp[i-1][0], -prices[i])
            dp[i][1] = max(dp[i-1][1], + prices[i] + dp[i-1][0])
            dp[i][2] = max(dp[i-1][2], - prices[i] + dp[i-1][1])
            dp[i][3] = max(dp[i-1][3], + prices[i] + dp[i-1][2])
        return dp[-1][-1]

买卖股票最佳时机4

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        # 甲:这n天怎样买股票赚的多-------------------------------------
        n = len(prices)

        # 乙:dp[i]代表第i天-------------------------------------------
        # 乙:dp[i][偶数]代表第i天过后第?次买股票时的最大收益
        # 乙:dp[i][奇数数]代表第i天过后第?次卖股票时的最大收益
        dp = [[0, 0]*k for _ in range(n)]

        # 乙: 今天是第一天---------------------------------------------
        # 乙: 第一次买股票是吧,prices[0]块钱拿去,今天股票我买了
        # 乙: 第一次卖股票是吧,prices[0]块钱买来又卖掉,血赚0元
        # 乙: 第二次买,我买了又卖掉又买回来,花费prices[0]块钱
        # 乙: 第二次买,我买了又卖掉又买回来又卖掉,哎,就是玩
        # 乙: 第k次同理
        # 注: 在同一天内反复买卖是不影响最终结果的,因为反正都是0
        dp[0] = [-prices[0], 0]*k

        # 旁白: 时间一天天过去
        for i in range(1, n):
             # 第j次买卖股票
             for j in range(k):
                # 甲: 今天是第i天,如果我第j次买股票,该怎么操作------
                # 乙: 跟题目三一样,自己看去
                # 甲: ??
                dp[i][j*2] = max(dp[i-1][j*2], -prices[i] + (dp[i-1][j*2-1] if j!=0 else 0))
                dp[i][j*2+1] = max(dp[i-1][j*2+1], dp[i-1][j*2] + prices[i])

        return dp[-1][-1]
无注释代码如下


class Solution:
    def maxProfit(self, k: int, prices: List[int]) -> int:
        n = len(prices)
        dp = [[0, 0]*k for _ in range(n)]
        dp[0] = [-prices[0], 0]*k
        for i in range(1, n):
            for j in range(k):
                dp[i][j*2] = max(dp[i-1][j*2], -prices[i] + (dp[i-1][j*2-1] if j!=0 else 0))
                dp[i][j*2+1] = max(dp[i-1][j*2+1], dp[i-1][j*2] + prices[i])
        return dp[-1][-1]

最佳买卖股票时机含冷冻期

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        # 甲:这n天怎样买股票赚的多-------------------------------------
        n = len(prices)

        # 乙:dp[i]代表第i天-------------------------------------------
        # 乙:dp[i][0]代表第i天过后手上有股票时的最大收益
        # 乙:总之,今天过后我必有股票在手上,要么之前买的,要么今天买的
        # 乙:dp[i][1]代表第i天过后手上无股票时的最大收益
        # 乙:总之,今天过后我手上空空如也,要么本来就没有,有我也给卖了
        dp = [[0, 0] for _ in range(n)]

        # 乙: 今天是第一天---------------------------------------------
        # 乙: 保证必须有股票是吧,prices[0]块钱拿去,今天股票我买了
        # 乙: 保证没有股票,啥都不干就好了
        dp[0] = [-prices[0], 0]

        # 旁白: 时间一天天过去
        for i in range(1, n):
            # 甲: 今天是第i天,如果我一定要保证自己有股票,该怎么操作------
            # 乙: dp[i-1][0] 今天的股票太贵了,买之前的股票更划算
            # 乙: - prices[i] 今天的股票更便宜,我买了,prices[i]块钱拿去
            # dp[i-2][1]是我之前卖股票赚的钱,隔一天保证冷冻期
            dp[i][0] = max(dp[i-1][0], - prices[i] + (dp[i-2][1] if i > 1 else 0))

            # 甲: 今天是第i天,如果我一定要保证自己没有股票,该怎么操作------
            # 乙: dp[i-1][1] 今天股市不行,还是之前卖更划算
            # 乙: + prices[i] + dp[i-1][0] 今天的行情不错,股票卖掉,血赚prices[i]块钱,
            # dp[i-1][0]是我用低价买入花的钱
            dp[i][1] = max(dp[i-1][1], + prices[i] + dp[i-1][0])

        return dp[-1][-1]
无注释代码如下


class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        dp = [[0,0] for _ in range(n)]
        dp[0] = [-prices[0], 0]
        for i in range(1, n):
            dp[i][0] = max(dp[i-1][0], - prices[i] + (dp[i-2][1] if i > 1 else 0))
            dp[i][1] = max(dp[i-1][1], + prices[i] + dp[i-1][0])
        return dp[-1][-1]

买卖股票的最佳时机含手续费

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        # 甲:这n天怎样买股票赚的多-------------------------------------
        n = len(prices)

        # 乙:dp[i]代表第i天-------------------------------------------
        # 乙:dp[i][0]代表第i天过后手上有股票时的最大收益
        # 乙:总之,今天过后我必有股票在手上,要么之前买的,要么今天买的
        # 乙:dp[i][1]代表第i天过后手上无股票时的最大收益
        # 乙:总之,今天过后我手上空空如也,要么本来就没有,有我也给卖了
        dp = [[0, 0] for _ in range(n)]

        # 乙: 今天是第一天---------------------------------------------
        # 乙: 保证必须有股票是吧,prices[0]块钱拿去,今天股票我买了
        # 乙: 保证没有股票,啥都不干就好了
        dp[0] = [-prices[0], 0]

        # 旁白: 时间一天天过去
        for i in range(1, n):
            # 甲: 今天是第i天,如果我一定要保证自己有股票,该怎么操作------
            # 乙: dp[i-1][0] 今天的股票太贵了,买之前的股票更划算
            # 乙: - prices[i] 今天的股票更便宜,我买了,prices[i]块钱拿去
            # dp[i-1][1]是我之前卖股票赚的钱
            dp[i][0] = max(dp[i-1][0], - prices[i] + dp[i-1][1])

            # 甲: 今天是第i天,如果我一定要保证自己没有股票,该怎么操作------
            # 乙: dp[i-1][1] 今天股市不行,还是之前卖更划算
            # 乙: + prices[i] + dp[i-1][0] 今天的行情不错,股票卖掉,血赚prices[i]块钱,
            # dp[i-1][0]是我用低价买入花的钱,去掉小费即可
            dp[i][1] = max(dp[i-1][1], + prices[i] + dp[i-1][0] - fee)

        return dp[-1][-1]
无注释代码如下


class Solution:
    def maxProfit(self, prices: List[int], fee: int) -> int:
        n = len(prices)
        dp = [[0,0] for _ in range(n)]
        dp[0] = [-prices[0], 0]
        for i in range(1,n):
            dp[i][0] = max(dp[i-1][0], - prices[i] + dp[i-1][1])
            dp[i][1] = max(dp[i-1][1], + prices[i] + dp[i-1][0] - fee)
        return dp[-1][-1]
代码

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        dp = [[0,0,0,0] for _ in range(n)]
        dp[0]=[-prices[0],0,-prices[0],0]
        for i in range(1,n):
            dp[i][0] = max(dp[i-1][0], -prices[i])
            dp[i][1] = max(dp[i-1][1], + prices[i] + dp[i-1][0])
            dp[i][2] = max(dp[i-1][2], - prices[i] + dp[i-1][1])
            dp[i][3] = max(dp[i-1][3], + prices[i] + dp[i-1][2])
        return dp[-1][-1]

参考资料
https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iii/solution/yi-tao-mo-ban-ji-xing-dai-ma-bi-zhao-yan-0ap8/

你可能感兴趣的:(数据结构,动态规划,leetcode,算法)