Dynamic Programming Template
套路一:基本 1 型(時間序列)
觀念:
- 給一 sequence, 每個元素可以被視為一天, 且「今天」的狀態只取決於「昨天」的狀態
套路:
- 定義
dp[i][j]
代表第i
輪的第j
個狀態 - 想辦法將
dp[i][j]
與前一輪的狀態dp[i - 1][j]
產生關聯 - 最終的結果是
dp[last][j]
中的某種 aggregation(min, max, sum…)
例題:
- 198. House Robber
- 213. House Robber II
- 121. Best Time to Buy and Sell Stock
- 123. Best Time to Buy and Sell Stock III
- 309. Best Time to Buy and Sell Stock with Cooldown
- 376. Wiggle Subsequence
- 256. Paint House
- 487. Max Consecutive Ones II
- 1186. Maximum Subarray Sum with One Deletion
- 903.Valid Permutations for DI Sequence
套路二:基本 2 型(加強版時間序列)
觀念:
- 給一 sequence, 每個元素可以被視為一天, 且「今天」的狀態取決於之前「某一天」的狀態, 需要進行挑選
套路:
dp[i]
表示第i
輪的狀態, 通常這個狀態必須與元素i
直接有關- 想辦法將
dp[i]
與之前的狀態dp[j]
產生關聯, 其中1 ≤ j < i
- 最終的結果是
dp[i]
中的其中一個
例題:
- 300. Longest Increasing Subsequence
- 368. Largest Divisible Subset
- 1105. Filling Bookcase Shelves
- 983. Minimum Cost For Tickets
套路三:雙序列型
觀念:
- 給兩個 sequence
s
、t
, 讓你對它們搞事情
套路:
dp[i][j]
代表s[1:i]
、t[1:j]
的 subproblem 求解- 將
dp[i][j]
跟之前的狀態dp[i - 1][j]
、dp[i][j - 1]
、dp[i - 1][j - 1]
去做轉移 - 最終的結果是
dp[m][n]
例題:
- 1143. Longest Common Subsequences
- 1092. Shortest Common Supersequences
- 72. Edit Distance
- 115. Distinct Subsequences
- 727. Minimum Window Subsequence
套路四:區間 1 型
觀念:
- 給一 sequence
s
, 明確要求分割成k
個區間, 要你計算這些區間某個最優性質
套路:
dp[i][k]
代表s[1:i]
分割成k
個區間時所能得到的最優解- 搜尋最後一個區間的起始位置
j
, 將dp[i][k]
分割成dp[j - 1][k - 1]
和s[j:i]
- 最終的結果是
dp[n][k]
例題序列型:
- 1278. Palindrome Partitioning III
- 813. Largest Sum of Averages
- 410. Split Array Largest Sum
- 1335. Minimum Difficulty of a Job Schedule
套路五:區間 2 型
觀念:
- 給一 sequence
s
, 求針對該 sequence 的最優解
套路:
dp[i][j]
代表s[i:j]
的 subproblem 求解- 將大區間
dp[i][j]
往小區間dp[i'][j']
轉移- for loop 外層循環是區間大小
- for loop 內層循環是起始位置
- 最終的結果是
dp[1][n]
例題:
- 516. Longest Palindromic Subsequence
- 312. Burst Balloons
- 375. Guess Number Higher or Lower II
- 1246. Palindrome Removal
- 546. Remove Boxes
套路六:背包型
觀念:
- 給
n
件物品, 每個物品可用、可不用(或者有若干個不同的用法), 要求以某個有上限c
的代價來實現最大收益 - 有時候會反過來,要求以某個有下限的收益來實現最小代價
套路:
dp[i][c]
代表考慮只從前i
件物品的 subset 中選擇、代價為c
的最大收益
其中c = 1, 2, ..., C
(逐個列舉)- 將
dp[i][c]
往dp[i - 1][c']
轉移, 也就是考慮如何使用物品i
, 對代價/收益的影響- 外層循環是物品編號
i
- 內層循環是遍歷「代價」所有可能的值
- 外層循環是物品編號
- 最終的結果是
max{dp[n][c]}
, forc = 1, 2, ..., C
例題:
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Zako's Blog!
評論