本文中的链接有的是题解有的是题目链接,已经搞混了...

一.DFS(深度优先搜索)

过于水略过。

二.BFS(广度优先搜索)

同上。

三.记忆化

记忆化搜索,就是我们的状态会重复利用,为了防止状态的重复计算耗费不必要的时间,我们可以把这个状态的结果记录下来,然后查询表中的结果就行了。

一般来所,记忆化搜索是和DP等价的。如果递推的DP不好写,可以考虑用记忆化搜索实现,但是因为是递归,所以常数略大。记忆化搜索有明显的优点,就是可以不用考虑状态在哪里终止,只用知道状态会终止就行了。

四.搜索剪枝

这是一门博大精深的学问, 通常用于解决搜索时间复杂度过高的问题。

原理就是在庞大的搜索树上剪去不可能对答案产生贡献的枝条。

搜索+剪枝的时间复杂度是$O(玄学)$,因为我们只能通过经验来估测剪枝效果。

所以考试打暴力的时候一定要多写剪枝,尤其是奇形怪状的玄学剪枝。

几道例题:

1. Noip2015斗地主  。

贪心出牌,出完顺子枚举出其他的尽可能出的多的牌的组合。

加上最优化剪枝,如果现在出了$ans-1$次没有出完就剪枝。

2.Noip2009靶形数独

我当时用了$lowbit$优化常数,然后把整个棋盘分成上下两部分,如果上半部分空位比下半部分多,就从下半部开始搜索。这样就水过去了。

其实也可以按格搜索,优先搜可填的少的格。

还有$A^*$剪枝,如果剩下的格子都填9还比$ans$小的话就剪枝。

通常使用的剪枝技巧

1.最优性剪枝。

2.$A^*$剪枝。

3.改变搜索顺序,优先搜索扩展出的状态比较少的状态。

五.双向广搜

双向广搜就是从起点和终点开始搜索,每次各搜一层,如果相遇,则得出答案。

双向广搜可以使搜索树减少一半以上,大大优化了时间复杂度。

广度双向搜索通常有两种方法:

  1. 两个方向交替扩展

  2. 选择结点个数较少的那个方向先扩展.

方法2克服了两方向结点的生成速度不平衡的状态,明显提高了效率。

1.poj3523The Morning after Halloween

其实这题直接$bfs$就可过,但是为了追求效率,用双向广搜甚至可以减少一半的时间。

六.meet in the middle

这个和双向搜索有差别,思路是把问题折半,然后合并,减少一半的搜索层数。

经典例题NOI2001方程的解数

先搜前3个解,把结果用hash表存一下,然后搜后3个解,在hash表中查询个数。

这题太恶心了,用mapT飞,用hash表Mle,大力取模WA。

无药可救...

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <map>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
#define reg register
inline int read() {
int res=;char ch=getchar();bool fu=;
while(!isdigit(ch))fu|=(ch=='-'), ch=getchar();
while(isdigit(ch))res=(res<<)+(res<<)+(ch^),ch=getchar();
return fu?-res:res;
} int n, m;
int k[], p[];
int mi[][];
int ans;
map <int, int> mp;
void dfs1(int dep, int sum)
{
if (dep > n / ) {
mp[sum]++;
return ;
}
for (reg int i = ; i <= m ; i ++)
dfs1(dep + , sum + k[dep] * mi[i][p[dep]]);
} void dfs2(int dep, int sum)
{
if (dep > n) {
ans += mp[-sum];
return ;
}
for (reg int i = ; i <= m ; i ++)
dfs2(dep + , sum + k[dep] * mi[i][p[dep]]);
} int main()
{
n = read(), m = read();
for (reg int i = ; i <= n ; i ++) k[i] = read(), p[i] = read();
for (reg int i = ; i <= m ; i ++)
{
mi[i][] = ;
for (reg int j = ; j <= m ; j ++) mi[i][j] = mi[i][j - ] * i;
}
dfs1(, );
dfs2(n / + , );
cout << ans << endl;
return ;
}

方程的解数

七.迭代加深搜索(IDDFS)

某些题状态无限,bfs无法承受空间复杂度,可以限制dfs搜索的深度。

每次增加深度限制,每次可能对之前搜过的状态多次计算,但是由于状态每一层都扩展的十分多,所以相比于扩展一层,重复上面的状态的复杂度还是可以接受的。

1.codevs1288 埃及分数

可以逐步增加答案的分数的个数,然后可以限制住状态的无限扩展...其实我不会233(逃.

2.poj2248 Addition Chains   (此题解访问人数已经突破100人啦!!)

和上面一样逐步扩展答案的个数,然后再加上一些十分有用的剪枝,才能A掉这题,详情见链接。

八.迭代加深A*(IDA*)

普通迭代加深搜索加入A*剪枝。

1.bzoj1085 骑士精神

估价函数的一小点变动可能导致时间上的很大的差别,详情点进链接看看。

2.poj2286The Rotation Game

估价函数为8-中间出现次数最多的数字的个数。

九.随机化

过于玄学,略过。

[专题练习] Part1 搜索的更多相关文章

  1. Leetcode之回溯法专题-212. 单词搜索 II(Word Search II)

    Leetcode之回溯法专题-212. 单词搜索 II(Word Search II) 给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在二维网格和字典中出现的单词. 单 ...

  2. Leetcode之回溯法专题-79. 单词搜索(Word Search)

    Leetcode之回溯法专题-79. 单词搜索(Word Search) 给定一个二维网格和一个单词,找出该单词是否存在于网格中. 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元 ...

  3. [kuangbin带你飞]专题一 简单搜索 题解报告

    又重头开始刷kuangbin,有些题用了和以前不一样的思路解决.全部题解如下 点击每道题的标题即可跳转至VJ题目页面. A-棋盘问题 棋子不能摆在相同行和相同列,所以我们可以依此枚举每一行,然后标记每 ...

  4. kuangbin专题 专题一 简单搜索 Oil Deposits HDU - 1241

    题目链接:https://vjudge.net/problem/HDU-1241 题意:问有几个油田,一个油田由相邻的‘@’,组成. 思路:bfs,dfs都可以,只需要遍历地图,遇到‘@’,跑一遍搜索 ...

  5. kuangbin专题 专题一 简单搜索 迷宫问题 POJ - 3984

    题目链接:https://vjudge.net/problem/POJ-3984 这个题目,emm,上代码,看的估计应该是刚开始接触搜索的,我带点注释,你能慢慢理解. #include <ios ...

  6. [kuangbin带你飞]专题一 简单搜索 - E - Find The Multiple

    //Memory Time //2236K 32MS #include<iostream> using namespace std; ]; //保存每次mod n的余数 //由于198的余 ...

  7. Leedcode算法专题训练(搜索)

    BFS 广度优先搜索一层一层地进行遍历,每层遍历都是以上一层遍历的结果作为起点,遍历一个距离能访问到的所有节点.需要注意的是,遍历过的节点不能再次被遍历. 第一层: 0 -> {6,2,1,5} ...

  8. [kuangbin带你飞]专题一 简单搜索 棋盘问题

    题来:链接https://vjudge.net/problem/OpenJ_Bailian-132 J - 棋盘问题 1.题目: 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别. ...

  9. [kuangbin带你飞]专题一 简单搜索

            ID Origin Title 454 / 1008 Problem A POJ 1321 棋盘问题   328 / 854 Problem B POJ 2251 Dungeon Ma ...

随机推荐

  1. glusterfs详解及kubernetes 搭建heketi-glusterfs

    本文包含: gluster各存储卷详解.创建及使用 gluster-kubernetes搭建glusterfs存储 前言 传统的运维中,往往需要管理员手动先在存储集群分配空间,然后才能挂载到应用中去. ...

  2. java 简单框架的运用

    Struts Struts是一个基于Sun J2EE平台的MVC框架,主要是采用Servlet和JSP技术来实现的. Struts框架可分为以下四个主要部分,其中三个就和MVC模式紧密相关:  1.模 ...

  3. C#基础知识总结(二)--泛型

    什么是泛型 我们在编写程序时,经常遇到两个模块的功能非常相似,只是一个是处理int数据,另一个是处理string数据,或者其他自定义的数据类型,但我们没有办法,只能分别写多个方法处理每个数据类型,因为 ...

  4. 集群某节点DataNode服务无法启动解决(报java.net.BindException:Address already in use错误)

    现象: 在集群中某节点, 启动DataNode服务后马上又Shutdown, 在操作系统没看到有DataNode的日志(可能是服务启动失败, 自动删除了日志文件),幸好在界面上可以查看报错的日志:   ...

  5. git使用和操作

    git提交日志的规范 为了更规范的开发,特别是团队协同开发,对于代码托管工具的提交上都会有要求的. 作为开发者,我们一定要注重提交日志的规范性,我们要对自己写的代码负责.提交日志规范很多,最近看到了一 ...

  6. centos赋予访问权限

    chmod u+x *.sh (代表授权现在所处的文件目录下的所有以:.sh的文件 启动tomcat:/usr/local/tomcat9/bin/shutdown.sh 关闭tomcat:/usr/ ...

  7. AppScan工具使用-实战一

    本文首发于简书https://www.jianshu.com/p/639cf894838e 工具已经安装完成,废话不多说,直接拿手上的项目使用一下. 1.打开工具,点击文件-新建 2.打开新建扫描 3 ...

  8. 痞子衡嵌入式:飞思卡尔i.MX RTyyyy系列MCU硬件那些事(1)- 官方EVK简介

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔i.MX RTyyyy系列MCU的配套EVK板. 半导体设计厂商发布任何一块MCU芯片新品,一般都会同步推出基于这款MCU的配套 ...

  9. jquery让form表单异步提交

    1.监听表单提交事件,并阻止表单提交 $("form").submit(function(e) { return false;//阻止表单提交 }) 2.拿到表单内容 let da ...

  10. selenium-05-问题2

    现在的项目组用开源的Selenium做测试,但不得不说,这个东东bug奇多,下面是我遇到的一些问题,有些提供了解决方法,有些则需要继续研究,希望对各位看官有所帮助. 一.不能从命令行运行Seleniu ...