初见安~这篇我们来讲讲深搜(DFS)

前文我们讲过了递归【这里是递推递归】,这里我们就要运用到啦~

所谓深搜,也顾名思义就是在深度上搜索,到了尽头则返回上一层,换一条路继续搜——也就是递归思想。

先看一道题了解一下吧:【中国邮递员问题】

对这道题就是很直白的dfs搜索目标。也正如题解里所言:很多dsf也可以用bfs实现,但与此同时也有很多是不能实现的。

比如搜索路径条数——

2N皇后

(本题出自计蒜客)

Description

给定一个 n*n 的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入 n 个黑皇后和 n 个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条斜线(包括正负斜线)上,任意的两个白皇后都不在同一行、同一列或同一条斜线(包括正负斜线)上。问总共有多少种放法?n 小于等于 8。

Input

输入的第一行为一个整数 n,表示棋盘的大小。接下来 n 行,每行 n 个 0 或 1 的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为 0,表示对应的位置不可以放皇后。

Output

输出一个整数,表示总共有多少种放法。

Sample Input 1

4
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1

Sample Output 1

2

Sample Input 2

4
1 0 1 1
1 1 1 1
1 1 1 1
1 1 1 1

题解

了解题目后,我们可以有个大概的思路:黑白皇后之间无所谓冲突,所以我们只要分别处理好并标记位置确定同色皇后之间不冲突即可。那我们不妨大胆(不怕超时)尝试一下:先处理黑皇后(先白也可以),每放一个都四下检查一次有没有同色皇后;到了最后一行且皇后数量达到了2N时就开始找白皇后or跳出递归,已走过所有路径。

下面是代码及详解:

#include<bits/stdc++.h>
using namespace std;
int n,a[10][10],k=0;
int cnt=0;//cnt计数bool in(int x,int y) //检查是否越界
{return 1<=x&&x<=n&&1<=y&&y<=n;
}void dfs(int i,int q)//黑标记2白标记3 ,i为到第几行了。
{if(i>n) return;//越界for(int j=1;j<=n;j++){if(in(i,j)&&a[i][j]==1)//在(i,j)位置四下搜索是否遇得到已放皇后{bool flag=1;for(int k=1;k<=i-1;k++)//第i行后面的确定是没放的,所以不必搜索{if(a[k][j]==q) flag=0;}//不用搜索同一行,因为放了就深入到下一行int tx=i-1,ty=j+1;while(in(tx,ty))//斜向搜索{if(a[tx][ty]==q) flag=0;tx--;ty++;}tx=i-1,ty=j-1;while(in(tx,ty)){if(a[tx][ty]==q) flag=0;tx--;ty--;}if(flag)//通过了以上的检查操作{a[i][j]=q;if(i==n&&q==2)//黑皇后放完了{dfs(1,3);}else if(i==n&&q==3) //搜索完毕,计数{cnt++;}else dfs(i+1,q);a[i][j]=1;//递归循环,复原}}}
}int main()
{cin>>n;for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)cin>>a[i][j];dfs(1,2); cout<<cnt<<endl;return 0;
}

我知道还有个问题叫做8皇后问题。【和上述思路差不多,可以去试一下】


OK,我们再来看一道题:

等边三角形

(本题出自YCOJ)

Description

小白手上有一些小木棍,它们长短不一,小白想用这些木棍拼出一个等边三角形,并且每根木棍都要用到。 例如,小白手上有长度为 1,2,3,3 的4根木棍,他可以让长度为1,2 的木棍组成一条边,另外 2 跟分别组成 2 条边,拼成一个边长为 3 的等边三角形。小白希望你提前告诉他能不能拼出来,免得白费功夫。

Input

首先输入一个整数 n(3 ≤ n ≤ 200),表示木棍数量,接下来输入 n 根木棍的长度 p_i(1 ≤ p_i ≤ 10000)。

Output

如果小白能拼出等边三角形,输出"yes",否则输出"no"。

Sample Input 1

5
1 2 3 4 5

Sample Output 1

yes

Sample Input 2

4
1 1 1 1

Sample Output 2

no

题解

我们知道等边三角形就是三边相等。所以这道题我们可以凑(强行枚举?)出结果来。当然本题只需要返回是否存在解,所以找到了就可以了。

下面是代码及详解——

#include<bits/stdc++.h>
using namespace std;
int n,num[200],s=0;
bool flag=0;
void dfs(int a,int b,int c,int i)//三边长及用到了第几个木棍
{if(flag==1) return;//已经找到解了就不用在找了if(a==b&&b==c&&a!=0&&i==n+1)//如果找到了:{flag=1;return;}if(i>n+1||a>s||b>s||c>s)//返回上一个,因为长度超过了{return;}dfs(a+num[i],b,c,i+1);//强行凑!(什么鬼……)dfs(a,b+num[i],c,i+1);dfs(a,b,c+num[i],i+1);
}
int main()
{cin>>n;for(int i=1;i<=n;i++){cin>>num[i];s+=num[i];}if(s%3!=0)//如果连总长都不能三等分的话,就不用考虑了。{cout<<"no"<<endl;return 0;}else{s=s/3;//s变为要凑出来的边长度dfs(0,0,0,1);}if(flag==1) cout<<"yes"<<endl;//flag标记else cout<<"no"<<endl;return 0;
}

最后,其实DFS有一个优化操作——迭代加深搜索。什么是迭代加深呢?就是搜索前先限定好深度搜,如果没搜到那么我们再更改深度。相当于是枚举答案。

画个图理解一下:假设我们枚举的深度一点点加深,那么搜索路径就是这样的:

只有当搜索深度为3的时候最后一个点才会被搜到。

这样搜看起来前面的点被重复搜了很多次,但其实效率多数时候是比一路搜到最深处的dfs要优秀一些的。

有一个不那么经典的迭代加深搜索题目:洛谷P2329 栅栏(fence8)。虽然是二分枚举的答案,但是也算是迭代加深的。

后期还有不少搜索的经典题目,欢迎到博客目录翻阅~

迎评:)

——End——

专题·深度优先搜索(DFS)【including 2N皇后,等边三角形,中国邮递员问题相关推荐

  1. 【算法很美】深入递归 (下)深度优先搜索DFS问题

    深搜.回溯.剪枝 深度优先搜索DFS 2.1 无死角搜索I 数独游戏 部分和 水洼数目 2.2 回溯和剪枝 n皇后问题 素数环 困难的串 小结 一些使用 2.1 无死角搜索I 数独游戏 你一定听说过& ...

  2. 一文搞定深度优先搜索(DFS)与广度优先搜索(BFS)【含完整源码】

    写在前面:博主是一位普普通通的19届双非软工在读生,平时最大的爱好就是听听歌,逛逛B站.博主很喜欢的一句话花开堪折直须折,莫待无花空折枝:博主的理解是头一次为人,就应该做自己想做的事,做自己不后悔的事 ...

  3. C++实现深度优先搜索DFS(附完整源码)

    C++实现深度优先搜索DFS C++实现深度优先搜索DFS完整源码(定义,实现,main函数测试) C++实现深度优先搜索DFS完整源码(定义,实现,main函数测试) #include <al ...

  4. C++用stack实现深度优先搜索DFS(附完整源码)

    C++用stack实现深度优先搜索DFS的实现 C++用stack实现深度优先搜索DFS的完整源码(定义,实现,main函数测试) C++用stack实现深度优先搜索DFS的完整源码(定义,实现,ma ...

  5. 深度优先搜索(DFS) 总结(算法+剪枝+优化总结)

    深度优先搜索(DFS) 总结(算法+剪枝+优化总结) 本文中会引用部分实例.文献资料来自不同的作者之手,由于资料整理比较困难,转载地址不在文中列举.如有侵权请联系我更换或删除!对于提供题解思路的各位大 ...

  6. 【算法入门】深度优先搜索(DFS)

    深度优先搜索(DFS) [算法入门] 郭志伟@SYSU:raphealguo(at)qq.com 2012/05/12 1.前言 深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍 ...

  7. 【数据结构与算法】2.深度优先搜索DFS、广度优先搜索BFS

    原文链接:https://blog.csdn.net/qq_41681241/article/details/81432634 总结 一般来说,广搜常用于找单一的最短路线,或者是规模小的路径搜索,它的 ...

  8. 深入浅出,详解深度优先搜索(DFS)

    深度优先搜索 如果把深度优先搜索比作一个人的话,那么这个人是一个执着的人,甚至倔强,不把一条路走到底不会返回(回溯),虽然执着倔强,但是他不傻,如果在探索的途中发现这条路走下去没有希望他会提前返回(剪 ...

  9. 深度优先搜索dfs算法刷题笔记【蓝桥杯】

    其实网上已经有不少dfs的算法笔记,但我之所以还再写一篇,主要是因为我目前见到的笔记,都有些太偏向理论了. 对于基础薄弱的或是没有基础的人(like me),有点不合适,因为看了,也不能说自己会了. ...

最新文章

  1. Yii框架2.0的视图和widgets表单的使用
  2. 【干货】如何引导免费用户成为付费用户
  3. 2010世界杯主题曲夏奇拉献唱《Waka Waka》
  4. POJ 1062.昂贵的聘礼
  5. 创建provider服务
  6. mac上配置php开发环境,Mac配置PHP开发环境
  7. jdk1.8配置(自我速成)
  8. vs的form标签引起css走样问题
  9. typora代码块语言linux命令,typora工具的使用以及MarkDown语法
  10. js可以控制文件上传的速度吗?
  11. NLP—3.文本特征工程及工具使用举例
  12. Python的time,datetime,string相互转换
  13. JAVA 如何反编译JAR文件
  14. 腾讯云对象储存-图片上传-删除图片
  15. linux之cut命令的用法
  16. 移动拨号上网开热点(不是360开热点,而是使用电脑自带的热点功能)详解
  17. PHP时间差七个小时怎么回事,php 怎么解决8小时时间差的问题
  18. cefsharp内嵌资源html的读取,C#(csharp)用CefSharp开发实现一个浏览器,抓取网站任意资源...
  19. 黑客入门常用的8种工具
  20. 深度学习 - 42.特征交叉与 SENET、Bilinear Interaction 与 FiBiNet

热门文章

  1. 怀着忐忑的心情,我来了B站实习,B站后端日常实习面经分享!
  2. VScode Java代码自动生成器
  3. Tensorflow 4. 训练过程,服务器宕机了一次,服务器重启之后加载保存的model.ckpt报错?
  4. 六、微信小程序发布流程
  5. 开脑洞,买买买网站的皮肤
  6. 删除用户帐户后,保留在桌面上的用户配置文件夹删除后会自动重新生成的问题...
  7. C++RAII机制(智能指针原理)
  8. js下载文件流,提示文件损坏问题
  9. Django创建类不含默认id列
  10. 2021-2022-2 ACM集训队每周程序设计竞赛(10) - 问题 A: 还原撕碎的字条,哄笑生气的毛毛 - 题解