描述
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).
Credits:
Special thanks to @Freezen for adding this problem and creating all test cases.
思路
这题是股票系列的第四题,前面三题为121、122、123。
在这题中,问题规模被扩大到最多可以使用K次交易所能取得的最大收益。
首先这还是一道DP的问题。
我们首先对于K对于分类,如果K的次数足够大,那么可能在每次股票上涨的时刻购买,所以对于这种情况,我们直接将所有股票上涨额累加起来即可:
if (k >= n / 2) {
// we have enough transactions times to earn all money
int profit = 0;
int temp;
for (int i = 0; i < n - 1; ++i) {
temp = prices[i + 1] - prices[i];
if (temp > 0) {
profit += temp;
}
}
return profit;
}
那么对于次数不够的情况,想起来其实比较困难,这道理我参考了LeetCode上的discussion。
对于DP,首先确定我们求解的状态,假设maxProfitByKTransactionsBeforeDayI[k][I] 为前I天使用最多k次交易能获得最大的收益。
状态转移方程:
说来这个逻辑挺复杂的,我自己也是很困难才理解,大概可以这么理解:
如果想第j天卖出股票并获得最大利润,就要在第m天买入,而这个m需要满足,在m
完整解答
class Solution {
public:
int maxProfit(int k, vector<int>& prices) {
// for weird input
if (prices.size() <= 1) {
return 0;
}
int n = prices.size();
if (k >= n / 2) {
// we have enough transactions times to earn all money
int profit = 0;
int temp;
for (int i = 0; i < n - 1; ++i) {
temp = prices[i + 1] - prices[i];
if (temp > 0) {
profit += temp;
}
}
return profit;
}
vector< vector<int> > maxProfitByKTransactionsBeforeDayI(k + 1, vector<int>(n, 0));
for (int i = 1; i <= k; ++i) {
int localMax = maxProfitByKTransactionsBeforeDayI[i - 1][0] - prices[0];
for (int j = 1; j < n; ++j) {
maxProfitByKTransactionsBeforeDayI[i][j] = max(maxProfitByKTransactionsBeforeDayI[i][j - 1], localMax + prices[j]);
localMax = max(localMax, maxProfitByKTransactionsBeforeDayI[i - 1][j] - prices[j]);
}
}
return maxProfitByKTransactionsBeforeDayI[k][n - 1];
}
};