LeetCode188 买卖股票的最佳时机IV

链接: https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv/description/

题面

给定一段时间内每天的股票价格,已知你只可以买卖各 k 次,且每次只能拥有一支股票,求最大的收益。

dp思路

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int maxProfit(int k, vector<int>& prices) {
int siz = prices.size();
vector<vector<vector<int>>> dp(k + 1, vector<vector<int>>(1 + siz, vector<int>(2, -0x3f3f3f)));
k = min(k, siz / 2 + 1);
// dp[i][j][0]表示i次交易第j天手中没有股票的最大利润 
// dp[i][j][1]表示i次交易第j天手中有股票的最大利润
// 以买入作为一次交易的开始
for (int i = 0; i <= siz; i++) {
dp[0][i][0] = 0;
}
for (int i = 0; i <= k; i++) {
dp[i][0][0] = 0;
}
for (int j = 1; j <= siz; j++) {
for (int i = 1; i <= k; i++) {
dp[i][j][0] = max(dp[i][j - 1][0], dp[i][j - 1][1] + prices[j - 1]);
dp[i][j][1] = max(dp[i][j - 1][1], dp[i - 1][j - 1][0] - prices[j - 1]);
}
}
return dp[k][siz][0];
}

简化

建立两个动态规划数组 buy 和 sell,对于每天的股票价格,buy[j] 表示在第 j 次买入时的最大收
益,sell[j] 表示在第 j 次卖出时的最大收益。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Solution {
public:
int maxProfit(int k, vector<int>& prices) {
int len = prices.size();
if (len < 2) {
return 0;
}
if (k >= len) {
int total = 0;
for (int i = 1; i < len; i++) {
if (prices[i] > prices[i - 1]) {
total += prices[i] - prices[i - 1];
}
}
return total;
}
vector<int> buy(k + 1, -0xffff), sell(k + 1, 0);
for (int i = 0; i < len; i++) {
for (int j = 1; j <= k; j++) {
buy[j] = max(buy[j], sell[j - 1] - prices[i]);
sell[j] = max(sell[j], buy[j] + prices[i]);
}
}
return sell[k];
}
};