- Best Time to Buy and Sell Stock IV
https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/description/
Difficulty:Hard
Total Accepted:71.3K
Total Submissions:281.1K
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 k transactions.
Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
Example 1:
Input: [2,4,1], k = 2
Output: 2
Explanation: Buy on day 1 (price = 2) and sell on day 2 (price = 4), profit = 4-2 = 2.
Example 2:
Input: [3,2,6,5,0,3], k = 2
Output: 7
Explanation: Buy on day 2 (price = 2) and sell on day 3 (price = 6), profit = 6-2 = 4.
Then buy on day 5 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3.
作为一道动态规划的题目,此题需要分析状态。
动态规划的题目之前接触过的主要是背包问题,练得还不够,正好此题涉及到。
关于初级的动态规划,还可以参考这篇博客:
https://blog.csdn.net/cr496352127/article/details/77934132?locationNum=10&fps=1
回到此题,既然是动态规划求解最优值,首先需要分解状态大事化小小事化了。
两个状态,买和卖。
b[i][j] 作为在第j的时间点最多买i次的最优值(即手上钱最多,可以把买回来或者不动)
s[i][j] 作为在第j的时间点最多卖i次的最优值(可以在这个时间点卖掉或者不动)
p作为对应时间点j的价格
由此,可以得到下面一列状态转变方程:
s[0][j]=0
b[ 1 ][ i ] = max( b[ 1 ][ i - 1 ], s[ 0 ][ i - 1 ] - p )
s[ 1 ][ i ] = max( s[ 1 ][ i - 1 ], b[ 1 ][ i - 1 ] + p )
b[ 2 ][ i ] = max( b[ 2 ][ i - 1 ], s[ 1 ][ i - 1 ] - p )
s[ 2 ][ i ] = max( s[ 2 ][ i - 1 ], b[ 2 ][ i - 1 ] + p)
.........
b[ k ][ i ] = max( b[ k ][ i - 1 ], s[ k-1 ][ i - 1 ] - p )
s[ k ][ i ] = max( s[ k ][ i - 1 ], b[ k ][ i - 1 ] + p)
转换为c++如下:
for (int p : prices) {
for (int i = 0; i < k; ++i) {
buy[i + 1] = max(buy[i + 1], sell[i] - p);
sell[i + 1] = max(sell[i + 1], buy[i + 1] + p);
}
}
因为最后的结束时间固定,所以二维数组简化为一维数组,用一个for(int p:prices)即可。
最后的代码如下:
class Solution {
public:
int maxProfit(int k, vector<int>& prices) {
if (k >= prices.size() / 2) {
int ans = 0;
for (int i = 1; i < prices.size(); ++i) {
ans += max(prices[i] - prices[i - 1], 0);
}
return ans;
}
vector<int> buy(k + 1, INT_MIN), sell(k + 1, 0);
for (int p : prices) {
for (int i = 0; i < k; ++i) {
buy[i + 1] = max(buy[i + 1], sell[i] - p);
sell[i + 1] = max(sell[i + 1], buy[i + 1] + p);
}
}
return sell[k];
}
};