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.
是121题的拓展,121是只做一次交易,而这道题是做2次交易,而通过这道题可以推广到k次交易
数组中的数字是每天的股票价格,可以买和卖两次,但是第二次的买必须是第一次卖掉之后,求最大的收益
思路:
定义dp[k+1][size]
dp[i][j] 表示第i次交易,在 j 时刻的收益(j 时刻可以没有交易)
第0行因为交易次数是0,所以没有收益,一整行都是0
3 3 5 0 0 3 1 4 (j)
0 0 0 0 0 0 0 0 0
1
2
(i)
第 i 次交易时, j 时刻如果选择不交易,收益是保持第i次,j-1时刻的收益,也就是dp[i][j - 1]
如果选择在j时刻卖掉,因为买入可以是从0到j-1的任何一个,设m=0~j-1
那么收益就是第i-1次交易时,m时刻的收益,减去买入m时刻的价格,加上现在在j时刻卖掉的价格,即
dp[i-1][m] - prices[m] + prices[j], for m = 0~ j - 1
要在m=0~j-1中取最大收益
max(dp[i-1][m] - prices[m] ) + prices[j], for m = 0~ j - 1
不需要在每个j时都遍历0~j-1,只需要保持实时更新最大差值即可
要在交易和不交易两种情况中取较大的值
dp[i][j] = max(dp[i][j - 1], max_diff + prices[j])
因为交易有2次
最后返回dp[2][prices.size() - 1]
int maxProfit(vector<int>& prices) {
if (prices.size() == 0) {
return 0;
}
vector<vector<int>> dp(3, vector<int>(prices.size(), 0));
//i: number of transactions, j: prices index..
for (int i = 1; i < dp.size(); i++) {
//因为j从1开始,所以每次初始要用0-prices[0]
int max_diff = -prices[0];
for (int j = 1; j < prices.size(); j++) {
dp[i][j] = max(dp[i][j - 1], max_diff + prices[j]);
//dp[i][j]已经用上一次的max_diff,本次的max_diff用本次的j更新
max_diff = max(max_diff, dp[i - 1][j] - prices[j]);
}
}
return dp[2][prices.size() - 1];
}