概述
动态规划的一种典型题型:
一般的动态规划都是
dp[n] = f(dp[x])
但是有一种题型的动态规划的转移方程是:
dp[n] = f(g[x])
g[x] = dp[x]
这种就是含状态机的动态规划问题
股票交易问题的通用解法:
-
定义动态数组:
dp[i][k][0] 代表当前天是第i天,已经交易k次,现在不持有股票的最大利润
dp[i][k][1] 代表当前天是第i天,已经交易k次,现在持有股票的最大例如 -
初始化:
初始化的方向主要有两个原则:没有交易的时候利润为0,不可能事件的利润为 -inf
第0天,如果还没持有股票,利润为0
第0天,已经持有股票,利润为-price[0] -
转移方程
# 卖出不消耗次数 # 第i天,已经进行k次交易,并且不持有股票,我的值要不然就是前一天已经进行k次交易且不持有股票。要不就是前一天只进行k次交易并且持有股票,然后今天我把股票卖掉 dp[i][k][0] = max(dp[i - 1][k][0], dp[i - 1][k][1] + prices[i]) # 买入消耗次数 # 第i天,已经进行k次交易,并且持有股票,我的值要不然就是前一天已经进行k次交易且持有股票。要不就是前一天只进行k-1次交易并且不持有股票,然后今天我把股票买回来 dp[i][k][1] = max(dp[i - 1][k][1], dp[i - 1][k - 1][0] - prices[i])
-
循环区间
for i in range(size): for k in range(max_K,0,-1): #k为什是倒叙呢,不理解?[max_k,1] pass
-
返回结果
最后一天,交易了max_k次,并且不持有股票的利润dp[-1][max_k][0]
题型:k为有限次
k为1次:121. 买卖股票的最佳时机
class Solution:
def maxProfit(self, prices) -> int:
max_K = 1
size = len(prices)
if size == 0:
return 0
# dp[i][k][j] i [0,size-1] k [0,max_K] j [0,1]
dp = [[[0, 1] for _ in range(max_K + 1)] for _ in range(size)]
for i in range(size):
for k in range(max_K,0,-1):
if i == 0: # 初始化
dp[i][k][0] = 0
dp[i][k][1] = -prices