题目描述
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete at most two transactions.
Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again).
样例
Example 1:
Input: [3,3,5,0,0,3,1,4]
Output: 6
Explanation: Buy on day 4 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3.
Then buy on day 7 (price = 1) and sell on day 8 (price = 4), profit = 4-1 = 3.
Example 2:
Input: [1,2,3,4,5]
Output: 4
Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are
engaging multiple transactions at the same time. You must sell before buying again.
Example 3:
Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.
算法1
DP $O(k*n)$
C++ 代码
// f[k][i]: 第0到i天,最多k次transaction的最大获利。注意最后一次sell不一定在第i天做。
// f[k][i] = max { 第i天什么都不干: f[k][i-1],
// 第i天卖出第m天买入的stock: x[i]-x[m] + f[k-1][m]
// }
// 注意: 这里是f[k-1][m]而不是f[k-1][m-1],因为可以这样想,上一笔可以是在第m天卖出的,
// 然后立刻就在m天再买入,是合法的,虽然这之间没有任何profit.
// res = f[k][n-1]
// 时间复杂度: K x n x n
// loop m 可以优化:max( x[i] - x[m] + f[k-1][m] ), for m = 0..i-1
// --> x[i] + max( f[k-1][m] - x[m] ) for m=0..i-1
// 用一个moving_max, 与外面i的loop一起算,简化掉 loop m。时间复杂度 O(k x n x n) -> O(k x n)
// k = 0..K+1, i=0..n-1
// init f[0][i] = 0, f[k][0] = 0
int maxProfit(vector<int>& xs) {
int n = xs.size();
if(n<=1) return 0;
int k_trans = 2;
vector<vector<int>> f(k_trans+1, vector<int>(n, 0));
for(int k=1; k<=k_trans; k++) {
int t_max = f[k-1][0]-xs[0];
for(int i=1; i<n; i++) {
f[k][i] = max( f[k][i-1],
xs[i] + t_max );
t_max = max(t_max, f[k-1][i] - xs[i]);
}
}
return f[k_trans][n-1];
}
};