1. 买卖股票 含冷冻期
- 本题难点在于 正确区分出 股票的状态
- 持有股票 (当天买入, 本来就持有) 当天买入又分为 持有前一天是冷冻期 和 前一天非冷冻期
- 不持有股票:非冷冻期不持有, 冷冻期持有
- 冷冻期: 冷冻期所持有的现金与冷冻期前一天卖出股票后的钱一样
- 初始化: dp[0][0] 初始化为-prices[0] 其他都初始化为0 (要思考为什么其他天是0就可以)
class Solution {
public:
int maxProfit(vector<int>& prices) {
/* 股票的四个状态:
持有股票的状态
将不持有股票的状态分为三类;
卖出股票的当天(后一天会处于冷冻期);
保持卖出股票的状态(非卖出当天);
冷冻期
*/
// 1.dp数组以及下标的含义: dp[i][j]代表了第i天,状态为j的时候所剩的最多的现金
// 2.股票的具体状态
// 持有状态: 今天买入 或者是 之前买入后一直没卖出
// 2.不持有状态:
// 保持不持有的状态(前两天就卖出去的,度过了一天的冷冻期)
// 今天卖出的股票
// 3.冷冻状态: 卖出后只维持一天
int len = prices.size();
vector<vector<int>> dp(len, vector<int>(4, 0));
// 初始化
dp[0][0] = -prices[0];
for(int i=1; i<len; i++){
// 持有股票的状态,本来就就持dp[i-1][0]
// 当天买入: 前一天是冷冻期dp[i-1][3]-prices[i], 前一天是保持卖出股票的状态 dp[i-1][1]-prices[i]
dp[i][0] = max(dp[i-1][0], max(dp[i-1][3] - prices[i], dp[i-1][1]-prices[i]));
// 不持有股票的状态(非卖出当天)
// 前一天就是不持有的状态dp[i-1][1]; 前一天是冷冻期dp[i-1][3]
dp[i][1] = max(dp[i-1][1], dp[i-1][3]);
// 不持有股票(卖出当天) dp[i-1][0] + prices[i]
dp[i][2] = dp[i-1][0] + prices[i] ;
// 冷冻期 dp[i-1][2]
dp[i][3] = dp[i-1][2];
}
// 卖出后处于冷冻期 和 不持有股票中的最大值
return max(dp[len-1][3], max(dp[len-1][1], dp[len-1][2]));
}
};
2. 买卖股票含有手续费
class Solution {
public:
int maxProfit(vector<int>& prices, int fee) {
// fee为每次交易时候需要支付的手续费
int len = prices.size();
// 1.股票的状态分为持有股票和不持有股票两个状态 dp[i][0] 持有, dp[i][j]不持有
vector<vector<int>> dp(len, vector<int>(2));
// 2. 初始化
dp[0][0] = -prices[0];
// 3. 确定递推公式
for(int i=1; i<len; i++){
// 持有股票: 原先就持有股票 dp[i-1][0]; 原先不持有当天买入 dp[i-1][1] - prices[i]
dp[i][0] = max(dp[i-1][0], dp[i-1][1] - prices[i]);
// 不持有股票: 原先就不持有 dp[i-1][1]; 原先持有当天卖出 dp[i-1][0] + prices[i] - fee
dp[i][1] = max(dp[i-1][1], dp[i-1][0] + prices[i] - fee);
}
return dp[len-1][1];
}
};