使用二维数组 dp[i][j] :第i天的状态为j,所剩下的最大现金是dp[i][j]
j的状态表示为:
- 0 表示不操作
- 1 第一次买入
- 2 第一次卖出
- 3 第二次买入
- 4 第二次卖出
- .....
除了0以外,偶数就是卖出,奇数就是买入,题目要求是至多有K笔交易,那么j的范围就定义为 2 * k + 1 就可以了
class Solution:
def maxProfit(self, k: int, prices: List[int]) -> int:
n = len(prices)
if n == 0:
return 0
dp = [[0 for _ in range(2*k+1)]for _ in range(n)]
#初始化i = 0时持有股票的日期
for j in range(1, 2*k, 2):
dp[0][j] = -prices[0]
for i in range(1, n):
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][2*k]
- 状态一:持有股票状态(今天买入股票,或者是之前就买入了股票然后没有操作,一直持有)
- 不持有股票状态,这里就有两种卖出股票状态
- 状态二:保持卖出股票的状态(两天前就卖出了股票,度过一天冷冻期。或者是前一天就是卖出股票状态,一直没操作)
- 状态三:今天卖出股票
- 状态四:今天为冷冻期状态,但冷冻期状态不可持续,只有一天!
j的状态为:
- 0:状态一
- 1:状态二
- 2:状态三
- 3:状态四
class Solution:
def maxProfit(self, prices: List[int]) -> int:
n = len(prices)
if n == 0:
return 0
#一共有四种状态,所以j为[0,3]
dp = [[0 for _ in range(4)]for _ in range(n)]
dp[0][0] = -prices[0] #今天持有股票
for i in range(1, n):
dp[i][0] = max(dp[i-1][0], max(dp[i-1][1]-prices[i], dp[i-1][3]-prices[i]))
dp[i][1] = max(dp[i-1][3], dp[i-1][1]) #前一天的状态是冷冻期也要考虑
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. Best Time to Buy and Sell Stock with Transaction Fee
dp[i][0] 表示第i天持有股票所得最多现金,dp[i][1] 表示第i天不持有股票所得最多现金。
class Solution:
def maxProfit(self, prices: List[int], fee: int) -> int:
n = len(prices)
if n == 0:
return 0
dp = [[0 for _ in range(2)]for _ in range(n)]
dp[0][0] = -prices[0]
for i in range(1, n):
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 max(dp[-1][1],dp[-1][0])