0309-最佳买卖股票时机含冷冻期
给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 。
设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):
你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
示例:
输入: [1,2,3,0,2]
输出: 3
解释: 对应的交易状态为: [买入, 卖出, 冷冻期, 买入, 卖出]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown
参考:
python
# 0309.最佳买卖股票时机-含冷冻期
class Solution:
def maxProfit(self, prices: [int]) -> int:
"""
动态规划-股票问题,类比122
状态:
- 1.买入股票状态, dp[i][0] = max(dp[i - 1][0], max(dp[i - 1][3], dp[i - 1][1]) - prices[i])
- 操作1,前一天为持有股票状态, dp[i][0] = dp[i-1][0]
- 操作2,今天买入了, max(dp[i - 1][3], dp[i - 1][1]) - prices[i]
- 前一天是冷冻期-状态四, dp[i-1][3]-prices[i]
- 前一天是保持卖出股票状态-状态二, dp[i-1][1]-prices[i]
- 2.保持卖出股票状态, dp[i][1] = max(dp[i-1][1], dp[i-1][3])
- 前一天是状态2
- 前一天是冷冻期,状态4
- 3.今天就卖出股票状态 dp[i][2] = dp[i-1][0]+prices[i]
- 前一天是买入股票状态,状态1,今天卖出
- 4.冷冻期, dp[i][3] = dp[i-1][2]
- 昨天卖出了股票,状态3
初始化:
- 状态1, 第一天就持有,dp[0][0] = -prices[0]
- 状态2,第0天没有卖出,dp[0][1] = 0
- 状态3,保持卖出,dp[0][2] = 0
- 状态4,同状态2
:param prices:
:return:
"""
length = len(prices)
if length == 0: return 0
dp = [[0]*4 for _ in range(length)]
dp[0][0] = -prices[0]
for i in range(1, length):
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[length-1][1], dp[length-1][3], dp[length-1][2])
def maxProfit_(self, prices: [int]) -> int:
"""
动态规划-优化空间
:param prices:
:return:
"""
length = len(prices)
if length == 0: return 0
dp = [[0] * 4 for _ in range(2)]
dp[0][0] = -prices[0]
for i in range(1, length):
dp[i%2][0] = max(dp[(i - 1)%2][0], max(dp[(i - 1)%2][3], dp[(i - 1)%2][1]) - prices[i])
dp[i%2][1] = max(dp[(i - 1)%2][1], dp[(i - 1)%2][3])
dp[i%2][2] = dp[(i - 1)%2][0] + prices[i]
dp[i%2][3] = dp[(i - 1)%2][2]
return max(dp[(length - 1)%2][3], dp[(length - 1)%2][2], dp[(length - 1)%2][1])
if __name__ == "__main__":
test = Solution()
test.maxProfit([1,2,4])
golang
package dynamicPrograming
// 动态规划-股票,含冷冻期
func maxProfit4(prices []int) int {
length := len(prices)
if length == 0 {return 0}
dp := make([][]int, length)
for i:=0;i<length;i++ {
dp[i] = make([]int, 4)
}
dp[0][0] = -prices[0]
for i:=1;i<length;i++ {
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[length-1][3], max(dp[length-1][2], dp[length-1][1]))
}
// 优化数组空间
func maxProfit4_(prices []int) int {
length := len(prices)
if length == 0 {return 0}
dp := make([][]int, 2)
for i:=0;i<2;i++ {
dp[i] = make([]int, 4)
}
dp[0][0] = -prices[0]
for i:=1;i<length;i++ {
dp[i%2][0] = max(dp[(i-1)%2][0], max(dp[(i-1)%2][3], dp[(i-1)%2][1])-prices[i])
dp[i%2][1] = max(dp[(i-1)%2][1], dp[(i-1)%2][3])
dp[i%2][2] = dp[(i-1)%2][0] + prices[i]
dp[i%2][3] = dp[(i-1)%2][2]
}
return max(dp[(length-1)%2][3], max(dp[(length-1)%2][2],dp[(length-1)%2][1]))
}
func max(a,b int) int {
if a > b {return a}
return b
}