掌中之物,未必在掌握之中。|

2021hych

园龄:2年7个月粉丝:2关注:2

总结与归纳之搜索

前言

暴力的升级即使搜索,一个完美的搜索算法是有资格碾压标算的。在一次吃瓜中(不要在意内容),一位退役了的国集竟然用 O(3n) 的搜索+玄学数据结构过了 n=1000!这让我深知搜索的重要性。本人的搜索薄弱,正需要总结归纳搜索的内容。

正文

PART1:深度优先搜索算法

俗称 dfs,其基本结构为:是先访问某点,然后从该点出发沿着某条路一直访问到底,接着从该点沿着另一条路一直访问到底,直到最后没有从该点出发的路为止。简洁的说:递归深入,不到底,不停搜,到底回溯,搜完停止。记住,这是指数级的算法,搜索是极易退化导致严重超时。所以一般要看搜索树的规模而定。

PART2:舞蹈链

引入基本的精确覆盖问题离散化版:给定一个01矩阵,你可以选择一些行,使得最终每列都恰好有一个1。算法自然是 Donald E. Knuth 提出的 X 算法,因为选择和删除的对象是行和列,朴素法会起飞,因此要用舞蹈链加速(舞蹈?)。可以发现一个经验,对于覆盖类(填东西)的问题可以尝试转化为精确覆盖问题,没啥好说的,因为,CSP 不考,啊啊啊。

PART3:剪枝技巧

dfs 的精髓,主要有:
搜索顺序优化:不同的搜索顺序有时候会造成不同规模的搜索树,规模越小越好。
排除等效冗余:面对等价的搜索子树,只要搜一边就好了。
可行性剪枝:对于可以迅速预见结果的状态,如果不可行,立马回溯。
最优性剪枝:面对最优问题,把当前状态,和以搜到的最优解比较,如过之后不可能更优,回溯。
记忆化:如果搜索的状态空间不是树形的,那么可以采用记忆化,这种题目有可能以 DP 为正解。

PART4:迭代加深

对于搜索树规模极大(甚至无穷),那么可能会在某个子树上浪费太多的时间,这类题目可以采用迭代加深,不停地限制深度,就是按层扩展,疑似 dfs 交杂 bfs

PART5:广度优先搜索

俗称 bfs,其基本结构为:先访问某点,然后按与该结点的距离从小到大依次访问,直到达到目标(或没有可访问的点)为止。简洁的说:不断拓展,没到达,不停搜,永不掉头,到达停止。在目标确定的时候,这是一个可以考虑的算法,但是超时的可能也是很大的。

PART6:广搜与队列变形

这个貌似很少用到(其实最短路基本就是这个的体现,所以这原则上是个最短路)。因此不做过多赘述。如果发现扩展代价不全为1,那么对于 0/1 图可以使用双端队列维护,更一般的在复杂度优秀的前提下用优先队列即可。

PART7:双向搜索

这个是骗分好手,相当于做两次搜索,每次搜一半(有些玄学题不一定要一半)。然后找相遇点,基本上只要正确性没问题,所有搜索都能这么做(时间复杂度也要过关)。

PART8:A*

这个本质就是做一个最好的打算,如果当前状态即使最好,也不符合某种条件,那么剪枝。不过也要用用优先队列维护,所以看复杂度。

PART9:IDA*

相比于 A* 大法。IDA* 更好用,首先他是用迭代加深搜索+A* 实现的算法,代码编起来也很容易。不过对于估价函数的设置,就得思考再三了。

总结

一般不考搜索,因为太无脑了,这种东西在图论上稍微可能会考一些,毕竟现在的竞赛更偏向于思维类的,而不是暴力,不过拿来骗分挺好的,比如双向搜索,在某些时候可以骗到很多的分(本人最高记录骗到状态压缩DP优化80分,纯搜索只有10分)。所以还是要搞好搜索呀。

本文作者:2021hych

本文链接:https://www.cnblogs.com/2021hych/p/16542029.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   2021hych  阅读(66)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起