深搜的剪枝技巧

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

相关文章
相关标签/搜索