309. 最佳买卖股票时机含冷冻期
动态规划
-
四个状态:
- 0: 买入状态
- 1: 保持卖出状态
- 2: 今天卖出状态
- 3: 处于冷冻期状态
-
递推公式:
-
达到买入股票状态(状态一)即:
dp[i][0],有两个具体操作:-
操作一:前一天就是持有股票状态(状态一),
dp[i][0] = dp[i - 1][0] -
操作二:今天买入了,有两种情况
- 前一天是冷冻期(状态四),
dp[i - 1][3] - prices[i] - 前一天是保持卖出股票状态(状态二),
dp[i - 1][1] - prices[i]
- 前一天是冷冻期(状态四),
所以操作二取最大值,即:
max(dp[i - 1][3], dp[i - 1][1]) - prices[i]那么
dp[i][0] = max(dp[i - 1][0], max(dp[i - 1][3], 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];
-
class Solution:
def maxProfit(self, prices: List[int]) -> int:
if len(prices) == 1:
return 0
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], 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[-1][1], dp[-1][2], dp[-1][3])
714. 买卖股票的最佳时机含手续费
动态规划
- 和122. 买卖股票的最佳时机 II一致,不过在售出时要减去fee
class Solution:
def maxProfit(self, prices: List[int], fee: int) -> int:
if len(prices) == 1:
return 0
dp = [ [0, 0] 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] = max(dp[i-1][1], dp[i-1][0]+prices[i]-fee)
return dp[-1][1]
贪心
-
使用贪心策略,就是最低值买,最高值(如果算上手续费还盈利)就卖。
-
买入日期:其实很好想,遇到更低点就记录一下。
-
卖出日期:这个就不好算了,但也没有必要算出准确的卖出日期,只要当前价格大于(最低价格+手续费),就可以收获利润,至于准确的卖出日期,就是连续收获利润区间里的最后一天(并不需要计算是具体哪一天)。
-
所以我们在做收获利润操作的时候其实有三种情况:
- 情况一:收获利润的这一天并不是收获利润区间里的最后一天(不是真正的卖出,相当于持有股票),所以后面要继续收获利润。
- 情况二:前一天是收获利润区间里的最后一天(相当于真正的卖出了),今天要重新记录最小价格了。
- 情况三:不作操作,保持原有状态(买入,卖出,不买不卖)
class Solution:
def maxProfit(self, prices: List[int], fee: int) -> int:
min_price = prices[0]
result = 0
for i in range(1, len(prices)):
if prices[i] < min_price:
min_price = prices[i]
if prices[i] > min_price + fee:
result += prices[i] - min_price - fee
min_price = prices[i] - fee
return result