给定一个整数数组prices
,其中第 prices[i]
表示第 i
天的股票价格 。
设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):
- 卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例 1:
输入: prices = [1,2,3,0,2] 输出: 3 解释: 对应的交易状态为: [买入, 卖出, 冷冻期, 买入, 卖出]
示例 2:
输入: prices = [1] 输出: 0
思路:这道题和前四道股票的题目又不一样了,新增了一个冷冻期的概念,但那四道题一路刷下来,对股票类型的题目还是稍微有点感觉的吧,核心思想肯定不会变,要不就是递推公式会变,要不就是设立的状态数变。
在前四道题目中,我们设立状态基本是两个:第i天持有股票和不持有股票。但这道题多了个冷冻期,那我们就多设一个冷冻期状态呗,一共三个状态,那够不够呢,我们来看题目对冷冻期的定义,是指前一天卖出股票,第二天进入冷冻期,那我们设立的状态哪个是表示前一天卖出股票呢,是不持有股票吗?我们在分析不持有股票状态的时候说的很清楚:它包含两种情况,前一天就不持有股票或今天把股票卖出,我们想要的是这第二种情况,所以我们得把这种情况摘出来,多加一种状态,共四种状态。
分析了这么多,理一下这道题的四个状态吧。
dp[i][0]:表示持有股票,dp[i][1]表示不持有股票,dp[i][2]表示今天卖出股票,dp[i][3]表示冷冻期状态。
然后分析每个状态的递推公式
首先dp[i][0],表示持有股票,分为几种情况呢,第一、前一天就持有股票了dp[i][0] = dp[i-1][0],第二、前一天没持有股票,今天买股票,dp[i][0] = dp[i-1][1]-prices[i],还有第三!前一天是冷冻期,今天买股票,dp[i][0] = dp[i-1][3]-prices[i]。
然后dp[i][1],表示不持有股票,分为几种情况呢,第一、前一天就不持有股票,dp[i][1] = dp[i-1][1],第二、前一天是冷冻期,也是不持有股票,dp[i][1] = dp[i-1][3]。
然后dp[i][2],表示今天卖出股票,这是从原来不持有股票那个状态移出来的,就一种情况,dp[i][2] = dp[i-1][0] + prices[i],前一天得持有股票,然后才能卖。
最后dp[i][3],表示冷冻期,只有前一天是状态2,也就是卖出股票,才会进入这个状态3,因此dp[i][3] = dp[i-1][2]。
好,分析了大半天,终于把最复杂的递推公式部分理清了,然后就是初始化,i依赖i-1的状态,因此需要初始化dp[0][0]~dp[0][3]的值。
dp[0][0]毫无疑问等于-prices[0],dp[0][1]表示今天不持有股票,要么不买要么是冷冻期,不过不管哪种情况都应该初始化为0,dp[0][2] 表示今天卖出股票,那得先买才能卖,也就是当天买入当天卖出,收益为0,故dp[0][2]初始化为0,dp[0][3],前一天是状态2,今天才能到状态3,因此dp[0][3]也初始化为0。
最后返回的结果是取状态1、2、3的最大值,状态0是买股票,是减去股票的价格,肯定不会是最大值,别的几种状态都可能达到最大值。
指路前四道股票题目的题解:
121.买卖股票的最佳时机:121. 买卖股票的最佳时机-CSDN博客
122.买卖股票的最佳时机Ⅱ:122. 买卖股票的最佳时机 II-CSDN博客
123.买卖股票的最佳时机Ⅲ:123. 买卖股票的最佳时机 III-CSDN博客
188.买卖股票的最佳时机Ⅳ:188. 买卖股票的最佳时机 IV-CSDN博客
代码(Python):
class Solution(object):
def maxProfit(self, prices):
dp = [[0]*4 for _ in range(len(prices))]
dp[0][0] = -prices[0]
for i in range(1,len(prices)):
dp[i][0] = max(dp[i-1][0],dp[i-1][1]-prices[i],dp[i-1][3]-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[len(prices)-1][1],dp[len(prices)-1][2],dp[len(prices)-1][3])