我觉得搜索是真的有趣(其实真的难)
搜索的本质
其本质就是在一张图上找出一条从起点到终点,满足某些条件的路径——夏季提高营搜索EX
搜索的模板
1.dfs
void dfs(int step)//可以加入其它有关状态
{
if(check())//如果满足跳出条件
{
...//方案数加一或者输出答案
return ;
}
...//可行性剪枝和最优性剪枝的最佳插入地点
for(...)
if(...)//这算一个劣质的剪枝
{
oper();
dfs(step+1);
re();
}
}
2.bfs
queue< > q;//可以改为优先队列进行优化
void bfs()
{
q.push(...);
while(q.empty()==0)
{
tmp=q.front();
q.pop();
if(...)
continue;//可行性剪枝和最优性剪枝的最佳插入地点
for(...)
if(...)
...;
q.push(...);
}
}
搜索的剪枝
想要优化搜索的复杂度,显然最直接的方法,就是尝试减少需要枚举的局面的数量,在一些特殊情况下,可能有一些特殊的优化的方法。
想要减少遍历枚举的局面数量,最简单的方法就是剪枝。——夏季提高营搜索EX
一般的剪枝有两种,即可行性剪枝和最优性剪枝。
可行性剪枝即是剪去那些不可能满足题设条件的状态,即在某种情况下不可能存在有效解,关键在于看得远,较多用于方案型搜索。
最优性剪枝即是剪去不可能成为最优解的状态,关键在于准确估计最值代价,较多用于最优性搜索。
预测越远,效果越佳。——夏季提高营搜索EX
搜索的剪枝确实是有套路的,(那又如何我反正不会用)
我们来看看常见的深搜套路
- 改变搜索方向 秋令营搜索第一题
- 改变状态减少搜索树子集 换个角度看问题
- 数学方法优化 (多用于数学题) 秋令营搜索第三、四题
- 玄学转换法 秋令营搜索第九题
- 按升序搜索 非常常见的操作
- 折半搜索
(我不会啊)
那么广搜呢
- map判重减少空间和搜索次数 'search'
(亲测不剪30) - 循环数组提高空间利用率
搜索剪枝前:7601ms 128000kb
搜索剪枝后:112ms 816kb
只加了三行代码,所以
剪枝真的很重要