算法竞赛——搜索思想进阶

前言

搜索常常是用于暴力枚举各种状态的常用手段,本文将简单介绍各类搜索的思想并不做过多展开,作为知识面的增宽,如若需要更多了解请参考百度百科、OI WIKI。

深度优先搜索(DFS Depth first search)

过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次.常常指利用递归函数方便地实现暴力枚举的算法

例题1:把正整数 n分解为 3 个不同的正整数,如6=1+2+3 ,排在后面的数必须大于等于前面的数,输出所有方案。

例题2:按照字典序输出自然数 1 到 nn所有不重复的排列,即 nn 的全排列,要求所产生的任一数字序列中不允许出现重复的数字。

广度优先搜索(BFS Breadth First Search)

其算法核心就是在树上做层次遍历
广泛应用于最短路径、最小步数问题,并用于AC自动机、拓扑排序等多类算法中。
例题1:走迷宫

记忆化搜索

用数组来记录已经搜索过的答案,其特点是不依赖任何 外部变量,答案以返回值的形式存在,而不能以参数的形式存在,对于相同一组参数,dfs 返回值总是相同的。所以遇到时直接返回能够大大的优化时间复杂度,其本质是动态规划。

剪枝搜索

暴力搜索时将一些不可能的作为答案的分支直接舍去
常见剪枝思路有:
最优性剪枝:判断一下当前解是否已经差于已有解。
极端法:考虑极端情况,如果最极端(最理想)的情况都无法满足,那么肯定实际情况搜出来的结果不会更优了。
调整法:通过对子树的比较剪掉重复子树和明显不是最有“前途”的子树。
数学方法:比如在图论中借助连通分量,数论中借助模方程的分析,借助不等式的放缩来估计下界等等。
Alpha——Beta剪枝

双向搜索

双向同时搜索的基本思路是从状态图上的起点和终点同时开始进行 广搜 或 深搜。如果发现搜索的两端相遇了,那么可以认为是获得了可行解。可以将复杂度指数型折半O(ab)->O(ab/2)
例题1:字符串变换

Meet in the middle

与双向搜索类似,其思想是搜索分块并合并答案
例题1:Light

双端搜索

BFS的进阶使用,用于处理最小步数的问题,其核心思想与dijstra最短路类似,只不过有时候图的状态可能不唯一,需要枚举图的状态。
例题1:电路维修

启发式搜索(heuristic search)

在普通搜索算法的基础上引入了启发式函数,该函数的作用是基于已有的信息对搜索的每一个分支选择都做估价,进而选择分支。简单来说,启发式搜索就是对取和不取都做分析,从中选取更优解或删去无效解。

A*

属于启发式搜索对BFS的优化,其启发函数构造方式是通过起点的距离函数与终点的距离函数二者之和,是一种在图形平面上,对于有多个节点的路径求出最低通过成本的算法,主要通过三角不等式来优化剪枝。
例题1:第K短路
例题2:八数码

迭代加深

深度优先搜索的优化,其核心思想是每次限制最大深度,然后依次增加搜索深度,直至找到答案,可以视为BFS的一种空间优化。
例题1:加成序列

IDA*

也叫做迭代加深的A算法,将A算法中的BFS改为了DFS
例题1:排书

你可能感兴趣的:(ACM教程,蓝桥杯,算法,图论,数据结构)