dp[i][j]
表示第i天在状态j下手上的现金数量- 递推公式:
- 首先确定有4种状态:
- 状态0:买入状态:之前买入保持或者今天买入
dp[i][0] = max(dp[i - 1][0], max(dp[i - 1][1], dp[i - 1][3]) - prices[i]);
- 状态1:卖出状态:两天前就卖出了,过了冷冻期,保持卖出状态
dp[i][1] = max(dp[i - 1][1], dp[i - 1][3]);
- 状态2:卖出状态:今天卖出
dp[i][2] = dp[i - 1][0] + prices[i];
- 状态3:冷冻期
dp[i][3] = dp[i - 1][2];
3.初始化
dp[0][0] = -prices[0]
dp[0][1] = 0
dp[0][2] = 0
dp[0][3] = 0
- 递推顺序:从前往后
class Solution {
public:
int maxProfit(vector<int>& prices) {
int prices_size = prices.size();
if (prices_size == 0) return 0;
vector<vector<int>> dp(prices_size, vector<int>(4, 0));
dp[0][0] = -prices[0];
for (int i = 1; i < prices_size; i++) {
dp[i][0] = max(dp[i - 1][0], max(dp[i - 1][1], dp[i - 1][3]) - 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[prices_size - 1][3], max(dp[prices_size - 1][2], dp[prices_size - 1][1]));
}
};
和单纯的买卖股票的题目思路一致,只不过卖出时多付一部分fee
class Solution {
public:
int maxProfit(vector<int>& prices, int fee) {
int n = prices.size();
if (n == 0) return 0;
vector<vector<int>> dp(n, vector<int>(2, 0));
dp[0][0] = -prices[0];
for (int i = 1; i < n; i++) {
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[n - 1][0], dp[n - 1][1]);
}
};