[Leetcode][動態規划] 買賣股票的最佳時機IV


一、題目描述

給定一個數組,它的第 i 個元素是一支給定的股票在第 天的價格。

設計一個算法來計算你所能獲取的最大利潤。你最多可以完成 k 筆交易。

注意: 你不能同時參與多筆交易(你必須在再次購買前出售掉之前的股票)。

示例 1:

輸入: [2,4,1], k = 2
輸出: 2
解釋: 在第 1 天 (股票價格 = 2) 的時候買入,在第 2 天 (股票價格 = 4) 的時候賣出,這筆交易所能獲得利潤 = 4-2 = 2 。

示例 2:

輸入: [3,2,6,5,0,3], k = 2
輸出: 7
解釋: 在第 2 天 (股票價格 = 2) 的時候買入,在第 3 天 (股票價格 = 6) 的時候賣出, 這筆交易所能獲得利潤 = 6-2 = 4 。
     隨后,在第 5 天 (股票價格 = 0) 的時候買入,在第 6 天 (股票價格 = 3) 的時候賣出, 這筆交易所能獲得利潤 = 3-0 = 3 。

二、問題分析

1、這是比較經典和復雜的動態規划問題,因為需要同時記錄兩個狀態,對狀態的定義也比較嚴格,值得好好分析

2、定義狀態:buy[i][j] 在第i天交易正好是第j次買入時能夠獲得的最大利潤;sell[i][j] 在第i天交易正好是第j次賣出時能夠獲得的最大利潤

3、狀態轉移:buy[i][j]=max(buy[i-1][j],sell[i-1][j-1]-prices[i]);sell[i][j]=max(sell[i-1][j],buy[i-1][j]+prices[i]);
4、初始狀態:buy[0~n-1][0]=INT_MIN,sell[0~n-1][0]=0;
5、最終狀態:sell[n-1][k]
6、其實可以省略i,只保留交易次數,需要注意的是當交易次數大於等於天數的一半,就可以把所有上升的天數相加

三、AC代碼
class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        int n = prices.size();
        if (n < 2 || k < 1)return 0;
        if (k >= n / 2)return getMax(prices);
        vector<int>buy(k + 1, INT_MIN), sell(k + 1,0);
        int i, j;
        for (i = 0; i < n; ++i) {
            for (j = 1; j <= k; ++j) {
                buy[j] = max(buy[j], sell[j - 1] - prices[i]);
                sell[j] = max(sell[j], buy[j] + prices[i]);
            }
        }
        return sell[k];
    }
private:
    int getMax(vector<int>&prices) {
        int res = 0;
        for (int i = 1; i < prices.size(); ++i) {
            if (prices[i] > prices[i - 1])
                res += (prices[i] - prices[i - 1]);
        }
        return res;
    }
};

 




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM