首先是深搜的模板:html
int ans = 最壞狀況, now; // now爲當前答案 void dfs(傳入數值) { if (到達目的地) ans = 從當前解與已有解中選最優; for (遍歷全部可能性) if (可行) { 進行操做; dfs(縮小規模); 撤回操做; } }
1.剪枝的概念:數組
實際上,對於搜索,其實就是一棵樹:優化
(樹醜,莫要介意)ui
那麼對於沒有剪枝的dfs,須要搜索整棵樹,而剪枝,就是將其中一部分枝幹減掉,使時間複雜度下降。spa
2.code
剪枝的原則:三個原則:正確性(這是剪枝優化的前提),準確性,高效性;htm
3.深搜的優化技巧:blog
1.優化搜索順序:不一樣的搜索順序會產生不一樣的搜索樹形態,其規模大小也相差甚遠get
2.排除等效冗雜:在搜索中,若咱們發現沿某幾條線路所達到的效果是同樣的,那麼咱們能夠只搜索其中的一條模板
3.記憶化:是啥?:
模板:
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