首先是深搜的模板: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