1.买卖股票的最佳时期
代码:
class Solution {
public:
int maxProfit(vector<int>& prices) {
vector<vector<int>> dp(prices.size(),vector<int>(2, 0));
// dp[i][0] 表示第i填持有股票的最大利润 (持有 != 当天买入)
// dp[i][1] 表示第i填不持有股票的最大利润
dp[0][0] = -prices[0];
dp[0][1] = 0;
for(int i = 1; i < prices.size(); i++){
dp[i][0] = max(dp[i - 1][0], -prices[i]);
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);
}
return dp[prices.size() - 1][1];
}
};
note:
dp数组的含义:dp[i][0]表示当天持有股票的最大利润;dp[i][1]表示当天不持有股票的最大利润
递推公式:
dp[i][0] = max(dp[i -1][0 ],dp[i - 1][1]) 第i天持有股票,有两种可能,一种是前一天就已经是持有股票的状态了,第i天只是去保持这种状态;另一种是,当天才去购买股票,由于题上说只能购买一支股票,因此直接在0的基础上-prices[i]
dp[i][1] = max(dp[i - 1][1],dp[i - 1][0] + prices[i] ),第i天不持有股票,也有两者可能,可能前一天就已经不持有股票了,第i天只是保持这种状态;另一种是,当天把股票卖出了,这种情况的前提是前一天已经持有股票了,因此为dp[i - 1][0] + prices[i]
dp数组的初始化:根据递推公式,我们需要初始化dp[0][0]和dp[0][1],按照dp数组的含义进行初始化即可,dp[0][0] = -prices[0] dp[0][1] = 0
遍历顺序:正序遍历,因为后面的元素的求值依赖于前一个元素
2.买卖股票的最佳时期2
代码:
class Solution {
public:
int maxProfit(vector<int>& prices) {
vector<vector<int>> dp(prices.size(),vector<int>(2,0));
// dp[i][0] 表示第i天持有股票的最大利润
// dp[i][1] 表示第i天不持有股票的最大利润
dp[0][0] = -prices[0];
dp[0][1] = 0;
for(int i = 1; i < prices.size(); 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[prices.size() - 1][1];
}
};
note:
和上题的区别在于,dp[i][0]的求法,因为本题不再限制只能购买一支股票,因此不需要在0的基础上当天购入股票了,而是在前一天不持有股票的基础上卖出股票,也就是dp[i - 1][1] - prices[i]
其它的都一样,就不写了。
3.买卖股票的最佳时期3
代码:
class Solution {
public:
int maxProfit(vector<int>& prices) {
vector<vector<int>> dp(prices.size(),vector<int>(5,0));
// dp[i][0] 没有进行任何操作
// dp[i][1] 第一次持有股票
// dp[i][2] 第一次不持有股票
// dp[i][3] 第二次持有股票
// dp[i][4] 第二次不持有股票
dp[0][1] = -prices[0];
dp[0][3] = -prices[0];
for(int i = 1; i < prices.size(); i++){
dp[i][1] = max(dp[i - 1][1], -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];
}
};
note:
dp数组的含义:因为这道题限制最多买两支股票,因此本题的状态要设置得多一点,区分开第一次买入和第二次买入的情况。
// dp[i][0] 没有进行任何操作
// dp[i][1] 第一次持有股票
// dp[i][2] 第一次不持有股票
// dp[i][3] 第二次持有股票
// dp[i][4] 第二次不持有股票
递推公式:总体都是一个思路,要不保持前一天的同样的状态,要不去在前一天的某种状态的基础上,去在当天进行改变。
dp[i][1] = max(dp[i - 1][1], -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]);
初始化:dp[0][0] = 0 dp[0][i] = - prices[0] dp[0][2] = 0 dp[0][3] = -prices[0] dp[0][4] = 0
遍历顺序:正序遍历,因为后面的元素的求值依赖于前一个元素