状态机DP,力扣188. 买卖股票的最佳时机 IV
状态机DP,力扣188. 买卖股票的最佳时机 IV
整数数组
prices
和一个整数k
,其中prices[i]
是某支给定的股票在第i
天的价格。一次只能参与一笔交易,最多可以进行k
笔交易,求最大利润。
-
确定状态
f[n+1][k+2][2]
,f[i][j][0]、f[i][j][1]
分别表示前i
天最多进行j
次交易,且在第i
天时 未持有股票/持有股票 所能获得的最大利润i
位置的取值为0~n-1
,在递推式中需要用到i-1
的状态,所以插入一个起始状态-1
,由于下标无法表示-1
所以让所有状态后移一位,总状态个数为n+1
个j
位置的取值为0~k
,k+1
个状态,在递推式中需要用到j-1
的状态,所以插入一个起始状态-1
,由于下标无法表示-1
所以让所有状态后移一位,总状态个数为k+2
个- 结束状态:
f[n][k + 1][0] = max(f[n][k + 1][0],f[n][k + 1][1])
-
递推式:
f[i][j][0] = max(f[i - 1][j][0], f[i - 1][j - 1][1] + prices[i - 1]);
f[i][j][1] = max(f[i - 1][j][1], f[i - 1][j][0] - prices[i - 1]);
-
初始化(边界条件),两种初始状态:1.合理初始状态=
0
2.非法初始状态=-INF
f[·][0][·] = -INF
,f[·][0][·]
表示原先的f[·][-1][·]
,j
为-1
时此状态为非法状态设为-INF
。f[0][j][0] = 0
,f[0][j][0]
表示第0
天未持有任何股票进行j
次交易的利润为0
。f[0][j][1] = -INF
,f[0][j][1]
表示原先的f[-1][j][1]
,i
取-1
表示为非法状态设为-INF
。
-
状态机表示
Code
int maxProfit(int k, vector<int> &prices)
{
int n = prices.size(), f[n + 1][k + 2][2];
memset(f, -0x3f, sizeof(f));
for (int i = 1; i <= k + 1; i++)
f[0][i][0] = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= k + 1; j++)
{
f[i][j][0] = max(f[i - 1][j][0], f[i - 1][j - 1][1] + prices[i - 1]);
f[i][j][1] = max(f[i - 1][j][1], f[i - 1][j][0] - prices[i - 1]);
}
return f[n][k + 1][0];
}
思路参考b站灵茶山艾府