188. Best Time to Buy and Sell Stock IV(买卖股票的最佳时机 IV)
题目大意
You are given an integer array prices
where prices[i]
is the price of a given stock on the i
th day, and an integer k
.
Find the maximum profit you can achieve. You may complete at most k
transactions: i.e. you may buy at most k
times and sell at most k
times.
Note: You may not engage in multiple transactions simultaneously (i.e., you must sell the stock before you buy again).
中文释义
给定一个整数数组 prices
,其中 prices[i]
是第 i
天给定股票的价格,以及一个整数 k
。
找出你能获得的最大利润。你最多可以完成 k
笔交易:即你最多可以买入 k
次,卖出 k
次。
注意:你不能同时进行多笔交易(即,你必须在再次购买前出售股票)。
示例
- 示例 1:
- 输入:
k = 2
,prices = [2,4,1]
- 输出:
2
- 解释:第 1 天买入(价格 = 2)并在第 2 天卖出(价格 = 4),利润 = 4-2 = 2。
- 输入:
- 示例 2:
- 输入:
k = 2
,prices = [3,2,6,5,0,3]
- 输出:
7
- 解释:第 2 天买入(价格 = 2)并在第 3 天卖出(价格 = 6),利润 = 6-2 = 4。然后第 5 天买入(价格 = 0)并在第 6 天卖出(价格 = 3),利润 = 3-0 = 3。
- 输入:
限制条件
1 <= k <= 100
1 <= prices.length <= 1000
0 <= prices[i] <= 1000
解题思路
使用动态规划(DP)来解决问题。当 k
过大时,问题转化为不限交易次数的情况。
步骤说明
- 初始化一个三维
dp
数组,dp[i][j][0]
表示第i
天进行了j
次交易后手里没有股票的最大利润,dp[i][j][1]
表示第i
天进行了j
次交易后手里有股票的最大利润。 - 遍历股票价格数组:
- 如果
i
为 0,进行初始化。 - 否则,更新
dp
数组的值。
- 如果
- 返回
dp[n - 1][k][0]
作为结果。
代码
class Solution {
public:
int maxProfit(int k, vector<int>& prices) {
int n = prices.size();
if (n == 0) return 0;
if (k >= n / 2) {
int profit = 0;
for (int i = 1; i < n; i++) {
profit += max(prices[i] - prices[i-1], 0);
}
return profit;
}
vector<vector<vector<int>>> dp(n, vector<vector<int>>(k + 1, vector<int>(2, 0)));
for (int i = 0; i < n; i++) {
for (int j = 1; j <= k; j++) {
if (i == 0) {
dp[i][j][0] = 0;
dp[i][j][1] = -prices[i];
} else {
dp[i][j][0] = max(dp[i - 1][j][0], dp[i - 1][j][1] + prices[i]);
dp[i][j][1] = max(dp[i - 1][j][1], dp[i - 1][j - 1][0] - prices[i]);
}
}
}
return dp[n - 1][k][0];
}
};