分而治之 (D&C) 和動態程式設計 (DP) 是偉大的演算法 - Franc0

banq 發表於 2021-11-27
演算法

Divide and Conquer (D&C:分而治之) 和Dynamic Programming (DP:動態程式設計)是偉大的演算法技術,兩者都將給定的問題分解為子問題並解決子問題(banq注:還原論 思維)。你如何選擇它們來解決特定的問題呢?

要回答這個問題,您首先需要了解子問題是否重疊。如果它們不重疊,您應該使用分而治之。如果它們重疊,您應該使用動態程式設計 。

 

分而治之 (D&C) 

讓我們考慮將問題 P 分解為 2 個較小的子問題 S1 和 S2。使用 D&C,您會:

  1. 分別解決S1和S2;
  2. 以某種方式組合它們兩個S1和S2
  3. 得到答案結果P

一個經典的例子是歸併排序,您可以通過以下方式對陣列進行排序:

  1. 將其劃分為 2 個子陣列
  2. 對 2 個子陣列進行獨立 排序
  3. 合併已排序的子陣列以獲得原始排序

這是兩個子問題沒有重疊、沒有相互依賴以找到解決方案。(banq:類似DDD有界上下文劃分)

  

動態程式設計 (DP)

對於 DP,您需要意識到的第一件事是 S1 和 S2 重疊。這是什麼意思 ?基本上,S1 和 S2 之間存在相互依賴關係。

假設 S2 依賴於 S1。這意味著必須先解決 S1,然後才能解決 S2。這正是 DP 在以自下而上的方式實施時所做的。

  1. 首先解決S1並記住結果。
  2. 利用 S1 的記憶結果求解 S2(S2 取決於 S1)
  3. 使用 S2 和 S1 的解求解 P。

您需要做的就是從底部 (S1) 開始並逐漸(通過 S2)向上 (P) 移動。

一個經典的例子是斐波那契數列:f(n) = f(n-1) + f(n-2)。f(n-1) 的解取決於 f(n-2) 的解。DP解決方案:

  1. 首先解決較小的數字的問題
  2. 重用這個值來計算較大的值
  3. 到最終值