- Published on
Dynamic Programming 動態規劃
- Authors
- Name
- Alan Hu
Overlapping Subproblems 重疊子問題 求解過程中,許多 subproblems 可能被重複計算。 DP 透過 cache 這些 subproblems 的結果,來避免重複計算。
可視為分治法的子集,分治法的主要區別: 動態規劃著重於 subproblems 的重疊性,以便通過 Memoization、Tabulation 來提高效率。
Optimal Substructure 最優子結構 一個問題的最優解,可以由其子問題的最優解來構建。
Cache
- Memoization 記憶化 (Top-down)
- Tabulation 表格化 (Bottom-up)
一般 Recursive
fun fibonacci(n: Int): Int {
return if (n <= 1) n else fibonacci(n - 1) + fibonacci(n - 2)
}
改用 DP
Tabulation (Bottom-up)
- 由最小 subproblem (Bottom) 開始,逐漸推到大(Up)。
- 通常使用迭代。
fun fibonacci(n: Int): Int {
val dp = IntArray(n + 1)
dp[0] = 0
dp[1] = 1
for (i in 2..n) {
dp[i] = dp[i - 1] + dp[i - 2]
}
return dp[n]
}
改進空間複雜度
fun fibonacci(n: Int): Int {
val dp = intArrayOf(0, 1)
for (i in 2..n) {
val last = dp[1]
dp[1] = last + dp[0]
dp[0] = last
}
return dp[1]
}
Memoization (Top-down)
- 直接由原本的 problem 開始,逐漸推到小(down)。
- 通常使用遞迴。
todo