不含冷冻期,动态规划解法
可以不使用动态规划,但是含冷冻期的股票问题就需要了,所以先铺垫一下:
这里可以对每一天定义两个状态:
dp[i][0]: 表示第i天不持股的最大利益
dp[i][1]: 表示第i天持股的最大利益
定义状态的记号,方便理解
< :表示买入股票,当第i天之前(包括第i天)买入了股票,是持股的状态
> :表示卖出股票,当卖出股票时定义为不持股的状态
, :表示什么都不做
不持股的状态 :<,,,>,,,<,,,>,,, 可以由前一天不持股、前一天持股但是今天刚好卖出,这两种状态推出
前一天持股但是今天刚好卖出:dp[i-1][1] + prices[i]
前一天不持股:dp[i-1][0]
于是:dp[i][0] = max(dp[i-1][1] + prices[i], dp[i-1][0])
持股的状态:<,,,>,,,<,,, 可以由前一天也持股、前一天不持股,但今天刚好买入, 这两种状态推出
前一天也持股 :dp[i-1][1]
前一天不持股,但今天刚好买入:dp[i-1][0] - prices[i]
dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])
# 定义边界,第0天的状态(初始状态)
dp[0][0] = 0 # 不持有
dp[0][1] = - prices[0] # 持有,最大利益为负
最终的代码如下:
class Solution:
def maxProfit(self, prices: List[int]) -> int:
length = len(prices)
if length == 0:
return 0
dp = [[0]*2 for _ in range(length)] # 初始化数组
# 定义边界,第0天的状态(初始状态)
dp[0][0] = 0 # 不持有
dp[0][1] = -prices[0] # 持有
for i in range(1,length):# price[1,length)
dp[i][0] = max(dp[i-1][1] + prices[i], dp[i-1][0])
dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])
return dp[length-1][0]
股票问题,含冷冻期,动态规划解法
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
定义状态与其中的状态转移是关键,
最容易想到的状态是:是否持有股票
定义状态的记号,方便理解
< :表示买入股票,当第i天之前(包括第i天)买入了股票,是持股的状态
> :表示卖出股票,当卖出股票时定义为不持股的状态
, :表示什么都不做
— :表示冷冻期
依然要定义两个状态,即持股与不持股,
但是对于不持股的状态要分成两种:
一种是:,,,<,,,> : 这一种表示今天刚好卖出而不持股,这种状态不能推出明天买入而持股的状态
一种是:,,,<,,,>_,, : 这一种表示今天没有卖出,并且也不持股,这种状态可以得到明天买入股票而持股的状态
由于上面的区别,所以需要将不持股的两种状态分开定义
对于持股的状态:
只有一种:,,,<,,,>_,,<,,,
因此需要定义三种状态:
,,,<,,,>_,,
dp[i][0]: 表示不持股的最大利益,而且今天也没有卖出,可以由前一天dp[i-1][0], dp[i-1][2]得来
,,,<,,,>_,,<,,,
dp[i][1]: 表示持股的最大利益,可以由前一天持股dp[i-1][1], dp[i-1][0] - prices[i] 得来
,,,<,,,>
dp[i][2]: 表示不持股,而且今天卖出的最大利益, 可以由dp[i-1][1] + price[i]得来
初始状态:
dp[0][0] = 0 # 可以定义为第0天不持股状态,这个状态是不可以推出第二天买入而持股的状态
dp[0][1] = -prices[0]
dp[0][2] = 0 # 可以定义为第0天买入又卖出的 不持股状态,这个状态是不可以推出第二天买入而持股的状态
以下是完整代码:
class Solution:
def maxProfit(self, prices: List[int]) -> int:
length = len(prices)
if length == 0:
return 0
dp = [ [0]*3 for _ in range(length) ]
dp[0][0] = 0
dp[0][1] = -prices[0]
dp[0][2] = 0
for i in range(1,length):
dp[i][0] = max(dp[i-1][0], dp[i-1][2]) # 不持有状态, 可有dp[i-1][2]以及dp[i-1][0] 得到
dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i]) # 持有股票的状态,可由 dp[i-1][2]以及dp[i-1][1]得到
dp[i][2] = dp[i-1][1]+prices[i] # 不持有,当天卖出的状态,可由dp[i-1][1] +prices[i] 得到
# print(dp)
return max(dp[length-1][0], dp[length-1][2])