1.dfs之剪枝与优化
dfs中剪枝跟优化可以分为4个部分
1.优化搜索顺序:
对于大多数情况下,我们优先搜索分支数量少的节点
在题目中一般是从大到小排个序,然后按照从大到小的顺序进行搜索2.排除等效冗余:
对于某一些特定的搜索方式,一个方案可能会被搜索很多次,例如:搜到3,2, 1和2,3,1是一样的(只考虑组合)。解决方案是自己定义一个所搜顺序,例如对于每一个数只能往后搜,不能往前搜,就保证不会有重复的方案。
3.可行性剪枝:
就是已知当前状态永远搜不到终点或者说是不满足题目条件,就可以直接减掉。
4.最优性剪枝:
用于解决一些最优解问题,如果当前搜索状态继续搜索下去不比已搜出来的最优解更优的话,就可以直接返回。
这篇题解具体说明了其中三种剪枝方式是如何运用到题目中去的
2.迭代加深
先说说普通的dfs和bfs
关于dfs:
dfs算法是沿着搜索树的根节点,一直遍历完该搜索树之后再回溯继续搜索的一种算法。缺点是可能会出现答案在搜索树层数很浅,在靠后的子树中,但由于搜索次序需要遍历完一棵搜索树所有的节点,所以导致效率低下。
关于bfs:
bfs算法是沿着搜索树的根节点,按层遍历完该搜索树所有节点的一种算法。缺点是可能会出现答案在搜索树层数很深的地方,导致效率低下。且如果是满二叉树这样的搜索树很可能会使在bfs的过程中队列爆掉。在层数很多的时候会占用很多的空间。
而迭代加深,我感觉是结合了bfs和dfs特点的一种搜索算法。
它的主要是思想是:在普通dfs上加了一个深度的限制,如果当前深度已经超过限制则直接返回。
相比dfs,如果答案在很浅的位置,则可以不用搜索到很深的节点,大大提高效率。
相比bfs,迭代加深随着深度限制的增加,虽然会重复搜索到搜过的部分,但是却是可以忽略不计的(举个例子,假如搜索数是一颗二叉树的形式,假设答案在第n层,前面的所有节点加起来也才2^n-1,跟第n层所有节点差不多,但是一般题目的搜索树每个节点不可能只有两个子节点,那么重复搜索的部分就更不值一提),而bfs搜的话,可能会出现搜索节点过多导致爆空间。
具体运用可以看看这篇题解:加成序列
3.双向dfs
双向dfs不是同时从两个方向dfs。对于一个很大的集合, 可以先搜索他的前半段,并且存储起来,然后搜索后半段,用二分等方法所搜储存起来的前半段,从而降低时间复杂度。
具体运用可以看看这篇题解:送礼物
4.ida*
ida*其实就是加强板的迭代加深,在迭代加深的过程加一个估价函数(预估当前状态到终点的步数)进行剪枝,其中估价函数需要满足:估计步数不大于实际步数,当然越接近实际步数效果越好。
具体运用可以看看这篇题解:排书