LeetCode 188株式売買のベストタイミングIV HERODINGのLeetCodeの道


整数配列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を得ることができた.
ヒント:
0 <= k <= 109
0 <= prices.length <= 1000
0 <= prices[i] <= 1000

ソース:力ボタン(LeetCode)リンク:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv著作権はインターネットの所有に帰属する.商業転載は公式の授権に連絡してください.非商業転載は出典を明記してください.
解題の構想:依然として動的な計画で解決することができて、しかし今回の方法は比較的に複雑で、ここの前のリンク、解釈はとても詳しくて、コードは以下の通りです:
class Solution {
     
public:
    int maxProfit(int k, vector<int>& prices) {
     
        if (prices.empty()) {
     
            return 0;
        }

        int n = prices.size();
        //         ,right       
        int left = 1, right = *max_element(prices.begin(), prices.end());
        //     ,     -1         
        int ans = -1;
        while (left <= right) {
     
            //          (   )
            int c = (left + right) / 2;

            //                         
            int buyCount = 0, sellCount = 0;
            int buy = -prices[0], sell = 0;

            for (int i = 1; i < n; ++i) {
     
                if (sell - prices[i] >= buy) {
     
                    buy = sell - prices[i];
                    buyCount = sellCount;
                }
                if (buy + prices[i] - c >= sell) {
     
                    sell = buy + prices[i] - c;
                    sellCount = buyCount + 1;
                }
            }

            //            k,        
            //              k,         ,          k  
            if (sellCount >= k) {
     
                //       kc
                ans = sell + k * c;
                left = c + 1;
            }
            else {
     
                right = c - 1;
            }
        }

        //         ,             
        //           ,            
        if (ans == -1) {
     
            ans = 0;
            for (int i = 1; i < n; ++i) {
     
                ans += max(prices[i] - prices[i - 1], 0);
            }
        }

        return ans;
    }
};


でも!私たちはやはり前の方法で解決することができます!以前の方法は2つの状態で表されていましたが、コードは以下の通りです.
class Solution {
     
public:
    int maxProfit(int k, vector<int>& prices) {
     
        vector<int> sell(k + 1, 0);
        vector<int> buy(k + 1, INT_MIN);
        for(auto &ele : prices)
        {
     
            for(int i = 1; i < k + 1; i ++)
            {
     
                buy[i] = max(buy[i], sell[i - 1] - ele);
                sell[i] = max(sell[i], buy[i] + ele);
            }
        }
        return sell[k];
    }
};