實作時,可以開一個長度為 N 的 DP 陣列,並且依照上面的想法,每當 i 增加一時(也就是剛進入迴圈時),更新兩個變數 maxDp 以及 best。
如下:
1 2 3 4 5 6
for (int i = 0; i < n; i++) { maxDp = max(maxDp, dp[i - 3]); best = max(best, maxDp, prices[i - 3]);
dp[i] = ... }
不過要注意 maxDp 要在 i≤3 時才能更新;best 要在 i≤1 時才能更新。並且對於兩數的初始值,maxDp 初始值等於 0,因為在什麼股票都還沒有賣出的情況下,最大獲利為 0;而 best 的初時值為 −∞,對於還沒進行第一次購買股票情況,我們不應該從這個 best 來轉移,因此將值設為 −∞ 來避免將從這個點轉移的狀態成為答案。
因此迴圈內部之狀態更新應該如下:
1 2 3 4 5 6 7 8
for (int i = 0; i < n; i++) { // i increase by 1, update `maxDp` and `best` if (i >= 3) maxDp = max(maxDp, dp[i - 3]); if (i >= 1) best = max(best, maxDp - prices[i - 1]);
// transition dp[i] = prices[i] + best; }
我們可以把 maxDp 以及 best 的更新移至 DP 轉移的下方:
1 2 3 4 5 6 7 8
for (int i = 0; i < n; i++) { // transition dp[i] = prices[i] + best;
// i is ready to increase by 1, update `maxDp` and `best` if (i >= 2) maxDp = max(maxDp, dp[i - 2]); best = max(best, maxDp - prices[i]); }
/** * Author: justin0u0<[email protected]> * Problem: https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/ * Runtime: 4ms * Time Complexity: O(N) * Space Complexity: O(N) */
classSolution { public: intmaxProfit(vector<int>& prices){ int n = prices.size(); vector<int> dp(n);
constint inf = 0x3f3f3f3f; int maxDp = 0, best = -inf; for (int i = 0; i < n; i++) { // i increase by 1, update `maxDp` and `best` if (i >= 3) maxDp = max(maxDp, dp[i - 3]); if (i >= 1) best = max(best, maxDp - prices[i - 1]);
// transition dp[i] = prices[i] + best; } for (int i = max(0, n - 3); i < n; i++) maxDp = max(maxDp, dp[i]); return maxDp; } };