188.买卖股票的最佳时机IV
思路:和买卖股票第III题很相近,上一题只允许买卖两次,而这一题允许k次
dp[i][0] 在第i天状态是 未买入所所持有的最大钱数
dp[i][1] 在第i天状态是 第1次买入所持有的最大钱数
dp[i][2] 在第i天状态是 第1次卖出所持有的最大钱数
...
dp[i][2k-1] 在第i天状态是 第k次买入所持有的最大钱数
dp[i][2k] 在第i天状态是 第k次卖出所持有的最大钱数
从中不难发现规律:如果是奇数则是购入股票
和之前一样:这一状态要么是之前状态的延续,要么是这一天刚发生。
dp[i][1] = max(dp[i-1][1],dp[i-1][0]-prices[i-1]) 要么是之前就已经买入 要么是这一次买入
dp[i][2] = max(dp[i-1][2],dp[i-1][1]+price[i+1]) 要么是之前就已经卖出 要么是这一次卖出
...
dp[i][2k-1] = max(dp[i-1][2k-1],dp[i-1][2k-2]-prices[i-1]) 要么是之前就已经买入 要么是这一次买入
dp[i][2k] = max(dp[i-1][2k],dp[i-1]2k-1]+price[i+1]) 要么是之前就已经卖出 要么是这一次卖出
代码:
class Solution {
public:
int maxProfit(int k, vector<int>& prices) {
vector<vector<int>> dp(prices.size()+1,vector<int>(2*k+1,0));
//初始化
for(int i=0;i<2*k;i++){
if(i%2!=0) dp[1][i]=-prices[0]; //如果是奇数则是购入股票
else dp[1][i]=0;
}
//遍历顺序
for(int i=2;i<=prices.size();i++){//遍历每一天
int j=1;
while(j<=2*k-1){
dp[i][j] = max(dp[i-1][j],dp[i-1][j-1]-prices[i-1]);//买入
dp[i][j+1] = max(dp[i-1][j+1],dp[i-1][j]+prices[i-1]);//卖出
j+=2;
}
}
return dp[prices.size()][2*k];
}
};
309.最佳买卖股票时机含冷冻期
思路:考虑到这次加入了冷冻期,对于状态的分类应该重新思考。我们这次将卖出状态分为两种:一种是保持卖出股票的状态,另一种是当天卖出股票的状态。第三种则是买入状态。
买入状态就是要么延续之前买入状态,要么当天买入。
在“保持卖出股票状态”时,该天要么是延续之前已经卖出股票的状态,要么是当天卖出股票
在“当天卖出股票状态时”,则只有当天卖出股票状态。
最后在最后一天的这两个状态中取利润最大值。
代码:
class Solution {
public:
int maxProfit(vector<int>& prices) {
//dp[i][1] 在第i天状态是 买入状态所持有的最大钱数
//dp[i][2] 在第i天状态是 保持卖出股票状态所持有的最大钱数
//dp[i][3] 在第i天状态是 卖出股票所持有的最大钱数
//dp[i][1] = max(dp[i-1][1],dp[i-1][2]+price[i-1]) 要么是之前就已经买入 要么是前一天为保持状态时买入
//dp[i][2] = max(dp[i-1][2],dp[i-1][3]) 要么是之前就已经卖出 要么是前一天卖出
//dp[i][3] = dp[i-1][1]+prices[i-1]
if(prices.size()<=1) return 0;
vector<vector<int>> dp(prices.size()+1,vector<int>(4));
//初始化
dp[1][1]=-prices[0];
dp[1][2]=0;
dp[1][3]=0;
//遍历顺序
for(int i=2;i<=prices.size();i++){//遍历每一天
dp[i][1] = max(dp[i-1][1],dp[i-1][2]-prices[i-1]);
dp[i][2] = max(dp[i-1][2],dp[i-1][3]);
dp[i][3] = dp[i-1][1]+prices[i-1];
}
return max(dp[prices.size()][2],dp[prices.size()][3]);
}
};
714.买卖股票的最佳时机含手续费
思路:没什么好说的,卖出股票当天扣一次手续费。
代码:
class Solution {
public:
int maxProfit(vector<int>& prices, int fee) {
if(prices.size()<=1) return 0;
vector<vector<int>> dp(prices.size()+1,vector<int>(2));
dp[1][0]=-prices[0]-fee;
dp[1][1]=0;
for(int i=2;i<=prices.size();i++){
dp[i][0]=max(dp[i-1][0],dp[i-1][1]-prices[i-1]-fee);
dp[i][1]=max(dp[i-1][1],dp[i-1][0]+prices[i-1]);
}
return dp[prices.size()][1];
}
};