C++实现LeetCode(188.买卖股票的最佳时间之四)攻略
题目描述
给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 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 。
思路分析
本题可以使用动态规划的思想来解决。
- 定义dp数组:利用一个三维数组dp[i][j][0/1]表示第i天,已经完成j笔交易,手中没有股票/手中有股票的最大利润。
- 状态转移方程:一个交易包括“购买股票”和“售出股票”两次操作,因此需要分别考虑这两种情况。在当前第i天,购买一支股票的最大利润等于前一天已经卖出一支股票,和前一天没有卖出股票且已经继续交易的最大利润中取最大值。售出股票的最大利润同理。
- 边界条件:当k > n/2时,问题退化为贪心算法,可转化为无限次交易具体请见LeetCode题解。
C++代码示例
class Solution {
public:
int maxProfit(int k, vector<int>& prices) {
int n = prices.size();
if(n == 0) return 0;
k = min(k, n / 2);
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 = k; j > 0; --j) {
if(i == 0) {
dp[i][j][0] = 0;
dp[i][j][1] = -prices[i];
continue;
}
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];
}
};
示例说明
以示例2为例,当k = 2时,可以将该问题转化为“12345”5天内最多交易2次股票问题:
- 购买一支股票的最大利润可以通过比较“1”0和“1”1中的最大值得到;售出股票的最大利润可以通过比较“1”1和“2”0中的最大值得到。
- 购买一支股票的最大利润可以通过比较“1”2和“1”3中的最大值得到;售出股票的最大利润可以通过比较“1”3和“2”1中的最大值得到。
- 购买一支股票的最大利润可以通过比较“4”0(0表示目前没有手中股票)和“4”1中的最大值得到;售出股票的最大利润可以通过比较“4”1和“5”0中的最大值得到。
- 购买一支股票的最大利润可以通过比较“4”2和“4”3中的最大值得到;售出股票的最大利润可以通过比较“4”3和“5”1中的最大值得到。
- 最后将“5”0股票不持有的最大利润返回即可。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++实现LeetCode(188.买卖股票的最佳时间之四) - Python技术站