LeetCode題解系列--188. Best Time to Buy and Sell Stock IV

描述

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次交易能獲得最大的收益。
狀態轉移方程:

maxProfitByKTransactionsBeforeDayI[k][i]=max(maxProfitByKTransactionsBeforeDayI[k][i1],max1<=m<j(maxProfitByKTransactionsBeforeDayI[k1][m]prices[m]))

說來這個邏輯挺複雜的,我自己也是很困難才理解,大概可以這麼理解:
如果想第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];
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章