描述
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];
}
};