优雅的暴力
主要想总结一下搜索神奇的优化办法。
第一梯队:(meet) (in) (the) (middle) 双搜
对于一些问题,从终点到起点和从起点到终点都是可逆的话,考虑meet in the middle。
可以将(2^n)搜索化为(2^{frac{n}{2}}) 就可以接受了。
对于一些求方案数的问题,可以从起点搜到中间,再用数据结构存起来,再从终点搜到起点,统计答案。
第一梯队:最优性剪枝
对于最优解的求法。若已经求出了一个可行的答案,假设当前答案已经大于这个已知答案了,则退出当前递归。
这种办法最常用也最好用。
第一梯队:可行性剪枝
经典例题就是虫蚀算了。
根据学长的(paper),
搜索的复杂度(=)搜索的处理系数( imes)搜索的节点数。
根据当前得到的状态,花费一定的代价检查未来的情况是否非法,可以剪枝。
第一梯队:启发式搜索
少的节点先搜索,多的节点后搜索。先根据估价函数先搜索期望答案更好的。这是在最优性搜索里出现的。
第一梯队:记忆化搜索
我觉得很多人弄反了,(dp)的实质是搜索,记忆化搜索。
配合哈希使用
第二梯队:随机化搜索
我不是搞笑的。这是真的。随机化真的可以优化期望时间复杂度。就拿虫食算举例,将枚举解的队列(random)_(shuffle)一下,期望时间复杂度就真的降下来!!
第二梯队:迭代加深
经典例题是数码问题,对于数码问题,我们可以从小到大先枚举(ans),然后根据(ans)的大小确定搜索的深度。
第二梯队:劣者靠后
经典例题是智慧珠游戏。
这道搜索如果从体积大的(优者)开始枚举,可以飞快跑过。
实质上是将限制条件多的先搜索,这样搜出来的状态数会减少。
没有优化复杂度,但是实际效果非常好。
第二梯队:结合的搜索
将高效算法和搜索结合起来。
对于一些问题,问题的原型无法匹配上那一种高效算法,但是这个问题却像那种高效算法的变种。这时可以先搜索,直到问题满足了那一种高效算法的条件,再用高效算法。比如跑了搜索跑(dp),一边二分一边搜索。先搜索再网络流。
第二梯队:鸽王搜索
对于有些搜索,求的是最好的答案,但是有时候我们时限可能要到了,可是搜索还没有完成。这个时候直接将已经搜出来的答案输出出来,因为这个答案很可能是最优的,只是需要确认罢了。
什么时候脑洞打开就加。