123.买卖股票的最佳时机III
https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iii/
class Solution {
public:
int maxProfit(vector<int>& prices) {
// 0 第一次持有股票
// 1 已经卖过一次股票
// 2 第二次持有股票
// 3 已经卖过两次股票
vector<vector<int>> dp(2, vector<int>(4, 0));
dp[0][0] = -prices[0];
dp[0][2] = -prices[0];
for (int i = 1; i < prices.size(); i++) {
// 第一次持有股票:可能是前一天就持有,可能是今天第一次买股票
dp[1][0] = max(dp[0][0], -prices[i]);
// 已经卖过一次股票:可能是前一天就已经卖过了,也可能是今天刚卖
dp[1][1] = max(dp[0][1], dp[0][0] + prices[i]);
// 第二次持有股票:可能是前一天就第二次持有股票了,也可能是今天刚买
dp[1][2] = max(dp[0][2], dp[0][1] - prices[i]);
// 已经卖过两次股票:可能是前一天就已经卖过了,也可能是今天刚卖
dp[1][3] = max(dp[0][3], dp[0][2] + prices[i]);
dp[0][0] = dp[1][0];
dp[0][1] = dp[1][1];
dp[0][2] = dp[1][2];
dp[0][3] = dp[1][3];
}
return dp.back().back();
}
};
188.买卖股票的最佳时机IV
https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iv/
class Solution {
public:
int maxProfit(int k, vector<int>& prices) {
//0 第一次买入股票
//1 已经卖过一次股票
//2k - 2 第k次买入股票
//2k - 1 已经卖过k次股票
vector<vector<int>> dp(2, vector<int>(2*k, 0));
for (int j = 0; j < k; j++) {
dp[0][2 * j] = -prices[0];
}
for (int i = 1; i < prices.size(); i++) {
dp[1][0] = max(dp[0][0], -prices[i]);
dp[1][1] = max(dp[0][1], dp[0][0] + prices[i]);
for (int j = 1; j < k; j++) {
dp[1][2 * j] = max(dp[0][2 * j], dp[0][2 * j - 1] - prices[i]);
dp[1][2 * j + 1] = max(dp[0][2 * j + 1], dp[0][2 * j] + prices[i]);
dp[0][2 * j - 2] = dp[1][2 * j - 2];
dp[0][2 * j - 1] = dp[1][2 * j - 1];
}
dp[0][2 * k - 2] = dp[1][2 * k - 2];
dp[0][2 * k - 1] = dp[1][2 * k - 1];
}
return dp.back().back();
}
};