121. 买卖股票的最佳时机
dp含义:dp[i][0]持有股最大金额,dp[i][1]不持有最大金额
递推公式:
dp[i][0] = max(dp[i - 1][0], -prices[i]);
dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);
初始化:
dp[0][0]:-price[0];
dp[0][1]:0
遍历顺序:从前往后
class Solution {
public:int maxProfit(vector<int>& prices) {int len=prices.size();if(len==0)return 0;vector<vector<int>>dp(len,vector<int>(2));dp[0][0]=-prices[0];dp[0][1]=0;for(int i=1;i<len;i++){dp[i][0]=max(dp[i-1][0],-prices[i]);dp[i][1]=max(dp[i-1][1],prices[i]+dp[i-1][0]);}return dp[len-1][1];}
};
122.买卖股票的最佳时机II
与上一题的唯一不同点在于递推公式,可以买卖多次
递推公式:
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]);
class Solution {
public:int maxProfit(vector<int>& prices) {int len = prices.size();vector<vector<int>> dp(len, vector<int>(2, 0));dp[0][0] -= prices[0];dp[0][1] = 0;for (int i = 1; i < len; 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]);}return dp[len - 1][1];}
};
123.买卖股票的最佳时机III
dp含义:
dp[i][0]不操作
dp[i][1]第一次持有
dp[i][2]第一次不持有
dp[i][3]第二次持有
dp[i][4]第二次不持有
递推公式:
dp[i][0]=dp[i-1][0]
dp[i][1]=max(dp[i-1][1],dp[i-1][0]-price[i])
dp[i][2]=max(dp[i-1][2],dp[i-1][1]+price[i])
dp[i][3]=max(dp[i-1][3],dp[i-1][2]-price[i])
dp[i][4]=max(dp[i-1][4],dp[i-1][3]+price[i])
初始化:
dp[0][0]=0
dp[0][1]=-price[0]
dp[0][2]=0
dp[0][3]=-price[0]
dp[0][4]=0
遍历顺序:从前往后遍历
class Solution {
public:int maxProfit(vector<int>& prices) {if (prices.size() == 0) return 0;vector<vector<int>> dp(prices.size(), vector<int>(5, 0));dp[0][1] = -prices[0];dp[0][3] = -prices[0];for (int i = 1; i < prices.size(); i++) {dp[i][0] = dp[i - 1][0];dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]);dp[i][2] = max(dp[i - 1][2], dp[i - 1][1] + prices[i]);dp[i][3] = max(dp[i - 1][3], dp[i - 1][2] - prices[i]);dp[i][4] = max(dp[i - 1][4], dp[i - 1][3] + prices[i]);}return dp[prices.size() - 1][4];}
};
188.买卖股票的最佳时机IV
跟上一题一样
把第二个维度用j来表达
初始化也用j来表示
class Solution {
public:int maxProfit(int k, vector<int>& prices) {if (prices.size() == 0) return 0;vector<vector<int>> dp(prices.size(), vector<int>(2 * k + 1, 0));for (int j = 1; j < 2 * k; j += 2) {dp[0][j] = -prices[0];}for (int i = 1;i < prices.size(); i++) {for (int j = 0; j < 2 * k - 1; j += 2) {dp[i][j + 1] = max(dp[i - 1][j + 1], dp[i - 1][j] - prices[i]);dp[i][j + 2] = max(dp[i - 1][j + 2], dp[i - 1][j + 1] + prices[i]);}}return dp[prices.size() - 1][2 * k];}
};
309.最佳买卖股票时机含冷冻期
dp含义:
dp[i][0] 持股
dp[i][1] 保持卖出股
dp[i][2] 卖出股
dp[i][3] 冷冻期
递推公式:
dp[i][0]:
1.前一天持股:
dp[i-1][0]
2.买股:
dp[i-1][3]-price[i]
dp[i-1][1]-price[i]
这三者取最大值
dp[i][1]:
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]
初始化:
dp[0][0]=-price[0]
dp[0][1]=0
dp[0][2]=0
遍历顺序:从前往后
class Solution {
public:int maxProfit(vector<int>& prices) {int n = prices.size();if (n == 0) return 0;vector<vector<int>> dp(n, vector<int>(4, 0));dp[0][0] -= prices[0];for (int i = 1; i < n; 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] = 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[n - 1][3], max(dp[n - 1][1], dp[n - 1][2]));}
};
714.买卖股票的最佳时机含手续费
买卖股票的最佳时机II的不同点:获利时减去手续费
class Solution {
public:int maxProfit(vector<int>& prices, int fee) {int n = prices.size();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]);}
};