Day 42 動態規劃 Part09

12点不睡觉还想干啥?發表於2024-08-13

188. 買賣股票的最佳時機 IV

做完上一道題後再看就簡單許多了。股票問題的重點就在於兩點:

  1. 找到所有的狀態
  2. 狀態如何轉移

對於本題,一共包含2*k種狀態(第1,2...k次持有,第1,2...k次賣出)。狀態間如何轉移呢?見下圖

class Solution {
    public int maxProfit(int k, int[] prices) {
        int[] states = new int[2*k];
        Arrays.fill(states, Integer.MIN_VALUE);
        for(int i = 0; i < prices.length; i++){
            for(int j = 0; j < k; j++){
                states[2*j] = Math.max(states[2*j], 
                    2*j == 0 ? -prices[i] : states[2*j-1] - prices[i]); 
                states[2*j+1] = Math.max(states[2*j+1], 
                    states[2*j] + prices[i]);
            }
        }
        return states[2*k-1];
    }
}

309. 買賣股票的最佳時機含冷凍期

難度還是挺大,儘管最後寫出來了,但感覺寫完自己也不是很確定。也是兩部,確定所有的狀態,再確定狀態如何轉移。

  1. 包含三種狀態,分別為 非冷凍(未持有) 冷凍(未持有) 持有
  2. 狀態轉移圖
  3. 確定好這兩點再去實現程式碼就不會亂套了

class Solution {
    public int maxProfit(int[] prices) {
        int[] stat = new int[3]; 
        // 三種狀態 
        //分別為 非冷凍(未持有) 冷凍(未持有) 持有
        stat[0] = 0; stat[1] = 0; stat[2] = -1 * prices[0];

        for(int i = 1; i < prices.length; i++){
            stat[0] = Math.max(stat[0], stat[1]);  //當天非冷凍 前一天非冷凍|前一天冷凍
            stat[1] = stat[2] + prices[i-1]; //當天冷凍  一定是前一天持有
            stat[2] = Math.max(stat[2], stat[0]-prices[i]);  //當天持有   前一天持有|今天非冷凍
        }
        return Math.max(Math.max(stat[0], stat[1]), stat[2] + prices[prices.length-1]);
        //最後一天三種狀態,非持有兩種, 持有需要賣出再比較
    }
}

714. 買賣股票的最佳時機含手續費

class Solution {
    public int maxProfit(int[] prices, int fee) {
        int stat1 = -1 * prices[0] - fee;
        int stat2 = 0;
        for(int i = 1; i < prices.length; i++){
            stat1 = Math.max(stat1, stat2 - fee - prices[i]);
            stat2 = Math.max(stat2, stat1 + prices[i]);
        }
        return stat2;
    }
}

相關文章