# Leetcode 309. Best Time to Buy and Sell Stock with Cooldown ###### tags: `Leetcode(C++)` 題目 : https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/ 。 想法 : DP最難的就是尋找最優子結構與轉移方程,連日來被電的飛起。 Step 1 : 首先,有三種狀態 : buy(i) = max(rest(i - 1) - price[i] , buy(i - 1)); sell(i) = max(buy(i - 1) + price[i] , sell(i - 1)); rest(i) = max(rest(i - 1) , sell(i - 1) , buy(i - 1)); buy(i) : 第i天買,或是不買。 sell(i) : 第i天賣,或是不賣。 rest(i) : 第i天休息。 Step 2 : 觀察一下,發現可以簡化 : rest(i) = sell(i-1); 為什麼? 因為賣掉那天肯定是最大的,就算沒賣也是sell(i-1) >= rest(i-1)。 Step 3 : 帶回原式將rest()替換掉 : buy(i) = max(sell(i - 2) - price[i], buy(i - 1)); sell(i) = max(buy(i-1) + price[i] , sell(i - 1)); Step 4 : 注意初始設值與邊界狀態。 第一天不可能賣、可能買第一天或是買第二天、可能第二天賣掉。 時間複雜度 : O(n)。 程式碼 : ``` class Solution { public: int maxProfit(vector<int>& prices) { int l = prices.size(), sell_2 ,sell_1, sell, buy_1, buy; if(l == 1) return 0; if(l == 2) return max(-1 * prices[0] + prices[1], 0); sell_2 = 0; sell_1 = max(sell_2 , -1 * prices[0] + prices[1]); buy_1 = max(-1 * prices[0] , -1 * prices[1]); for(int i = 2 ; i < l ; i++){ buy = max(sell_2 - prices[i], buy_1); sell = max(buy_1 + prices[i], sell_1); buy_1 = buy; sell_2 = sell_1; sell_1 = sell; //cout << buy_1 << " " << buy << " ; " << sell_2 << " " << sell_1 << " " << sell << endl; } return sell; } }; ```