思路一 正向反向扫描两次的DP
关键是两个子问题的定义:
1)这个日期为止,交易一次的最大收益
2)这个日期开始,交易一次的最大收益
问题的解就是遍历一遍,二者和最大值。而两个子问题都是通过基本的dp求解。
int maxProfit(vector<int> &prices) {
if (prices.size() <= 1) return 0;
vector<int> d(prices.size());
for (int i = prices.size()-2, x = 0; i >= 0;--i) {
x = max(prices[i+1] - prices[i] + x, 0);
d[i] = max(d[i+1], x);
}
int max_profit = 0;
for (int i = 0, x = 0;i < prices.size(); ++i) {
x = i > 0 ? max(prices[i] - prices[i-1] + x, 0) : 0;
max_profit = max(max_profit, x + d[i]);
}
return max_profit;
}
思路二 转化成最大m子段和(m=2)问题
先把原数组转化成差分数组,然后求这个数组的最大2个不重叠子数组的和。