1. 题目来源
2. 题目说明
3. 题目解析
该股票问题:可以买卖无限次,每笔交易不能重叠(指买入下支股票前需要将手中股票卖出)
股票问题四部曲:
[Edp] lc121. 买卖股票的最佳时机(dp)
[Edp] lc122. 买卖股票的最佳时机 II(dp+思维)
[Hdp] lc123. 买卖股票的最佳时机 III(dp+前后缀分解)
[Hdp] lc188. 买卖股票的最佳时机 IV(状态机模型dp+线性dp+空间优化)
思路:
- 理解一个买入卖出方式即能解决该问题
- 第 3 天买入,第 6 天卖出,那么价值为 v 6 − v 3 v6 - v3 v6−v3,其等价于 v 4 − v 3 + v 5 − v 4 + v 6 − v 5 = v 6 − v 3 v4- v3 +v5 - v4 + v6 - v5=v6-v3 v4−v3+v5−v4+v6−v5=v6−v3
- 抽象来讲即为:如果 i i i 天买入 j j j 天卖出,那么所获利润为 p j − p i p_j-p_i pj−pi,这个可以分解为 p i + 1 − p i + p i + 2 − p i + 1 + . . . + p j − 1 − p j − 2 − p j − 1 = p j − p i p_{i+1} - p_i + p_{i+2} - p_{i+1} +...+p_{j -1} - p_{j - 2} - p_{j -1} = p_j-p_i pi+1−pi+pi+2−pi+1+...+pj−1−pj−2−pj−1=pj−pi 这两者也是等价的
- 故我们相当于将一个区间段的交易分解为每一个小区间之间的交易总和。这里的区间指的是跨越天数的股票买卖,这里的小区间就是当天买入,次天卖出这样的操作。每一个区间段交易均可以这样分解
- 那么问题转化为:当天买入,次天卖出(这就是小区间)时
- 收益如果为正,意味着这次操作就可以获利,那么隔很多天买卖股票的操作就可以包含这个小区间,这段区间对最后收益贡献一个正值
- 收益如果为负,那么如果我们大区间包含了该段区间势必导致我们获利减小,故需要跳过该小区间,这段区间对最后收益贡献为 0
- 这些小区间收益为正的操作就是最优操作,其中能够首尾相连起来的就可以将其合并成一个大区间
这个转化思想还是挺重要的,留意。
总结: res += max{0,第 i 天的价格 - 前 i - 1 天的价格}
代码:
class Solution {
public:
int maxProfit(vector<int>& prices) {
int res = 0;
for (int i = 1; i < prices.size(); ++i)
res += max(0, prices[i] - prices[i - 1]);
return res;
}
};