#include <vector>
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 两次交易所能获得的最大收益
* @param prices int整型vector 股票每一天的价格
* @return int整型
*/
int maxProfit(vector<int>& prices) {
// write code here
// 看答案的
int n=prices.size();
// 这里为什么要初始化为最小值呢?,初始化为0为什么会错???
vector<vector<int>> dp(n,vector<int>(5,-10000));
// 第一天未持有
dp[0][0] = 0;
// 第一天持有
dp[0][1] = -prices[0];
for(int i=1; i<n; ++i)
{
// step1: 第一支股票都还没买入
dp[i][0] = dp[i-1][0];
// step2: 第一支股票买入; 但还未卖出
dp[i][1] = max(dp[i-1][1],dp[i-1][0]-prices[i]);
// step3: 第一支股票卖出; 那可能是之前卖出,或者是今天卖出;
dp[i][2] = max(dp[i-1][2],dp[i-1][1]+prices[i]);
//step4: 第二支股票买入; 但还未卖出,那可能是之前买入,或者今天买入;
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 max(dp[n-1][2], dp[n-1][4]);
// 参考 买卖股票的最好时机(二),选取dp[n-1][0]和dp[n-2][0],即最后两次不持股的两个最大值
// 这样做也是错的,这样做区别只是有没有算上第n天而已;
// int n = prices.size();
// vector<vector<int>> dp(n,vector<int>(2,0));
// // 第一天不持股
// dp[0][0] = 0;
// // 第一天持股
// dp[0][1] = -prices[0];
// for(int i=1; i<n; ++i)
// {
// // 卖掉是赚钱
// dp[i][0] = max(dp[i-1][0],dp[i-1][i]+prices[i]);
// // 买入是输钱
// dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i]);
// }
// return dp[n-1][0] + dp[n-2][0];
// 错误的思路:不是每次遇到降序就卖,有可能后面升得更高
// 方法一: 用数组对升序段进行保存,让后选取两段最大的就行;
// 方法二:用两个变量表示最大的两段升序段;
// int t_1 = 0;
// int t_2 = 0;
// int temp = 0;
// for(int i=1; i<prices.size(); ++i)
// {
// if(prices[i]>prices[i-1])
// temp += (prices[i]-prices[i-1]);
// if(prices[i]<prices[i-1] || (i==prices.size()-1 && temp!=0))
// {
// // t_1改变的时候,t_2也得改变,保存为原来t_1的值,即第二大值
// if(temp > t_1)
// {
// t_2 = t_1;
// t_1 = temp;
// }
// else if(temp > t_2)
// t_2 = temp;
// cout << i << ", " << temp << ", " << t_1 << ", " << t_2 <<endl;
// // 重置temp
// temp = 0;
// }
// }
// return t_1+t_2;
}
};