深搜的剪枝技巧

首先是深搜的模板:html

int ans = 最壞狀況, now;  // now爲當前答案
void dfs(傳入數值) { if (到達目的地) ans = 從當前解與已有解中選最優; for (遍歷全部可能性) if (可行) { 進行操做; dfs(縮小規模); 撤回操做; } }

1.剪枝的概念:數組

實際上,對於搜索,其實就是一棵樹:優化

(樹醜,莫要介意)ui

那麼對於沒有剪枝的dfs,須要搜索整棵樹,而剪枝,就是將其中一部分枝幹減掉,使時間複雜度下降。spa

 2.code

剪枝的原則:三個原則:正確性(這是剪枝優化的前提),準確性,高效性;htm

3.深搜的優化技巧:blog

  1. 優化搜索順序
  2. 排除等效冗雜
  3. 記憶化
  4. 最優性剪枝
  5. 可行性剪枝

1.優化搜索順序:不一樣的搜索順序會產生不一樣的搜索樹形態,其規模大小也相差甚遠get

2.排除等效冗雜:在搜索中,若咱們發現沿某幾條線路所達到的效果是同樣的,那麼咱們能夠只搜索其中的一條模板

3.記憶化:是啥?:

  • 不依賴任何 外部變量
  • 答案以返回值的形式存在,而不能以參數的形式存在(就是不能將 dfs 定義成這裏面的 nowans 不符合要求)。
  • 對於相同一組參數,dfs 返回值老是相同的

模板:

int g[MAXN];  //定義記憶化數組
int ans = 最壞狀況, now; void dfs f(傳入數值) { if (g[規模] != 無效數值) return;  //或記錄解,視狀況而定
  if (到達目的地) ans = 從當前解與已有解中選最優;  //輸出解,視狀況而定
  for (遍歷全部可能性) if (可行) { 進行操做; dfs(縮小規模); 撤回操做; } } int main() { ... memset(g, 無效數值, sizeof(g));  //初始化記憶化數組
 ... }

4.最優性剪枝:在搜索中致使運行慢的緣由還有一種,就是在當前解已經比已有解差時仍然在搜索,那麼咱們只須要判斷一下當前解是否已經差於已有解。

模板:

int ans = 最壞狀況, now; void dfs(傳入數值) { if (now比ans的答案還要差) return; if (到達目的地) ans = 從當前解與已有解中選最優; for (遍歷全部可能性) if (可行) { 進行操做; dfs(縮小規模); 撤回操做; } }

5.可行性剪枝:

在搜索中若是當前解已經不可用了還運行,也是在搜索中致使運行慢的緣由。

int ans = 最壞狀況, now; void dfs(傳入數值) { if (當前解已不可用) return; if (到達目的地) ans = 從當前解與已有解中選最優; for (遍歷全部可能性) if (可行) { 進行操做; dfs(縮小規模); 撤回操做; } }

下面咱們來看一個簡單的剪枝的例題:【洛谷p1025】數的劃分

 下面咱們來看一個超多剪枝的例題:【洛谷UVA307】小木棍Sticks

相關文章
相關標籤/搜索