代码随想录算法训练营第四十二天| DP9— 188. 买卖股票的最佳时机 IV,309. 买卖股票的最佳时机含冷冻期

开始漫长的补卡计划,这次是买卖股票系列的最后一天。88. 买卖股票的最佳时机 IV,309. 买卖股票的最佳时机含冷冻期,714. 买卖股票的最佳时机含手续费。分别对应K次买卖,包含冷冻期的买卖和包含手续费的买卖。包含手续费的买卖比较简单,直接把它当作股票价格涨了相应的费用就行。

188. 买卖股票的最佳时机 IV

188. 买卖股票的最佳时机 IV - 力扣(LeetCode)

买卖股票Ⅲ的升级版,最多K次买卖,Ⅲ相当于K=2 。但是还是比较简单的,因为整体思路变化不大,只需要多添加一维变量去监测K的奇偶变化就行(奇偶主要反映的是持有和未持有两种状态)。

首先是创建DP数组,行数为2k+1,就是每一次买卖都有第n次持有和第n次未持有的状态加上最初的初始状态。然后初始化也和之前一样,对每个奇数次初始为股票消费。然后遍历就是记住j从0出发,+1代表了持有的状态,+2代表了未持有的状态,然后依次循环就可以。感觉简单主要是思路上和之前没有太大变化,也就是题目中的状态没有多少变化。

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

        for j in range(1, 2*k, 2):
            dp[0][j] = -prices[0]
        
        for i in range(1, len(prices)):
            for j in range(0, 2*k-1,2):
                dp[i][j+1] = max(dp[i-1][j+1], dp[i-1][j]-prices[i])
                dp[i][j+2] = max(dp[i-1][j+2], dp[i-1][j+1]+prices[i])
        return dp[-1][k*2]

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

309. 买卖股票的最佳时机含冷冻期 - 力扣(LeetCode)

属于是Ⅱ的改版,在卖股票后加了一天冷冻期,但是本身是可以进行无限次买卖。感觉难得原因就是状态变化太快了,自己做的时候也尝试了更新一下状态,变为4种,分别是是否持有股票,是否进入冷静期,但是做起来的时候发现还有问题。

看了题解发现也是四种状态,但是定义有所不同,持有0,未持有1,今天卖出2,在冷冻期3。递推公式复制全一点,比较好理解。(有2和3的主要原因是要准确表明股票卖出的时间以及冷冻期开始的时间)

  1. 确定递推公式

达到买入股票状态(状态一)即:dp[i][0],有两个具体操作:

  • 操作一:前一天就是持有股票状态(状态一),dp[i][0] = dp[i - 1][0]
  • 操作二:今天买入了,有两种情况
    • 前一天是冷冻期(状态四),dp[i - 1][3] - prices[i]
    • 前一天是保持卖出股票的状态(状态二),dp[i - 1][1] - prices[i]

那么dp[i][0] = max(dp[i - 1][0], dp[i - 1][3] - prices[i], dp[i - 1][1] - prices[i]);

达到保持卖出股票状态(状态二)即:dp[i][1],有两个具体操作:

  • 操作一:前一天就是状态二
  • 操作二:前一天是冷冻期(状态四)

dp[i][1] = max(dp[i - 1][1], dp[i - 1][3]);

达到今天就卖出股票状态(状态三),即:dp[i][2] ,只有一个操作:

昨天一定是持有股票状态(状态一),今天卖出

即:dp[i][2] = dp[i - 1][0] + prices[i];

达到冷冻期状态(状态四),即:dp[i][3],只有一个操作:

昨天卖出了股票(状态三)

dp[i][3] = dp[i - 1][2];

最后一个注意的点是在最后return的时候,要在三种状态中取最大值,因为其实这三种状态都算在未持有的里面。感觉还是难在怎么想这些状态上了,然后就是需要想好怎么去做状态之间的转移。

class Solution:
    def maxProfit(self, prices: List[int]) -> int:

        n = len(prices)
        if n <= 1:
            return 0
        dp = [[0]*4 for _ in range(n)] 
        # 持有0 未持有1 卖出股票2 在冷冻期3

        dp[0][0] = -prices[0]
        
        for i in range(1,n):
            dp[i][0] = max(dp[i-1][0], max(dp[i-1][3],dp[i-1][1])-prices[i])
            dp[i][1] = max(dp[i-1][1], dp[i-1][3])
            dp[i][2] = dp[i-1][0] + prices[i]
            dp[i][3] = dp[i-1][2]

        return max(dp[n-1][2], dp[n-1][3], dp[n-1][1])

你可能感兴趣的:(算法,leetcode,职场和发展)