深度优先搜索(DFS)

深度优先搜索(DFS,DepthFirstSearch)简称深搜或者爆搜,DFS的搜索顺序是按照深度优先搜索,简单来说就是“一条路走到黑”,搜索是把所有方案都试一遍,再判断是不是一个可行解。搜索与“递归”和“栈”有很大的联系,递归是实现搜索的一种方式,而栈则是计算机实现递归的方式。每个搜索过程都对应着一棵递归搜索树,递归搜索树可以让我们更加容易的理解DFS。整个搜索过程就是基于该搜索树完成的,为了不重复遍历每个结点,会对每个结点进行标记,也可以对树中不可能是答案的分支进行删除,从而更高效的找到答案,这种方法被称为剪枝。如果搜索树在某个子树中搜索到了叶结点,想继续搜索只能返回上个或多个状态,返回的过程称为回溯,回溯要记得恢复状态,才能保证接下来的搜索过程可以正常进行。

题意:输出$n$的全排列

思路:以$n$为$3$举例,枚举每个位置上该填什么数,但是每一位上的数不能和其他位置上的数一样,填满了$3$位就输出,然后回溯继续搜索。

上图则是一棵递归搜索树,就是搜索的过程形象化的显示出来。从第一个数字开始填,在填第二个数字,填过的数字记得要标记一下“使用过了”,不然会导致三个数字有两个数字是重复的。上文提到的回溯,就是填完了三个数字,先输出答案,无法在继续搜索下去就要回溯,回溯记得要恢复状态,不然接下来无法填数。

算法思路:

intpath[10],st[10],n;voiddfs(intu){if(u==n)//u==n则说明填满了三个数{for(inti=0;i

DFS的思想和代码很容易理解,这里不再赘述,但初学者学不懂DFS的原因主要是不理解递归而理解不了DFS。这里来详细的讲解一下递归的执行过程。

进入入口则是主函数调用,先执行一段代码然后递归调用(对应上面的代码就是dfs(u+1)),如果某一次递归的过程的中触发了判断条件,则返回(回溯),回溯到上次执行我这次的递归的代码的下面再继续执行下面的代码,如图中的第一根红线,对应上面的代码是先输出了$123$,然后是第一次触发判断条件,这时$u$为$3$,就返回到$u$为$2$的这次递归上,然后不执行dfs(u+1),直接执行下面的代码。然后没代码可以执行了,就只能执行第$27$行的代码继续返回(回溯),然后再继续做接下来的操作。

剪枝的常见方法:

题目大意:给定若干个长木棍和若干的短木棍,让我们从长木棍中裁剪出若干个短木棍,问我们最多可以裁出多少根短木棍。每个长木棍和短木棍只能使用一次。

思路:数据范围只有$m\leq50$所以直接深搜就行了,但需要加一点剪枝优化。

剪枝$1$

排序$+$二分

先将长木棍和短木棍从小到大排序。

显然,我们裁的时候一定是从小到大裁剪的前$k$个,不妨设我们裁剪的不是最小的$k$个,那么我们裁剪最小的$k$个,方案数不会变少。

所以只需要裁剪从小到大的前$k$的短木棍就可以了,所以需要存一个短木棍的前缀和S[i]。

我们还可以发现,如果裁剪的是前$k$个短木棍的话,那么在$k$之前的一定可以裁剪,在$k$之后的一定不能裁剪,所以具有二段性,所以就可以二分了。

剪枝$2$(优化搜索顺序)

我们在判断前$k$个短木棍能不能裁剪出来的时候,直接搜索就可以了,可以从后往前枚举(即从大到小)短木棍。

从大到小枚举可以使搜索树的分支更少,从而更快的触发剪枝条件。

剪枝$3$(可行性剪枝)

我们开一个变量total来记录所有长木棍的总长度,如果total

剪枝$4$

如果某个长木棍的长度都要$<$最短的木棍的长度的话,那么也一定无解。

THE END
1.Python搜索算法深度优先搜索(DFS)算法原理详解与应用,示例+代码5.4 在树结构中进行深度遍历 深度优先搜索(DFS)是一种重要的图遍历算法,用于探索图中的节点和边。 1 基本原理 DFS 是一种递归或栈(堆栈)数据结构的算法,用于图的遍历。 从一个起始节点开始,尽可能深入图的分支,直到无法继续深入,然后回溯并探索其他分支。 https://blog.csdn.net/qq_35831906/article/details/133829680
2.C语言中深度优先搜索(DFS)算法的示例详解C语言这篇文章主要通过两个简单的示例为大家详细介绍一下C语言中深度优先搜索(DFS)算法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下+ 目录 GPT4.0+Midjourney绘画+国内大模型 会员永久免费使用!【 如果你想靠AI翻身,你先需要一个靠谱的工具!】 迷宫问题 有一个迷宫: S*****T (其中字符S表示起点,字符https://www.jb51.net/article/275489.htm
3.什么是深度优先搜索?详述深度优先搜索的原理?用C语言实现深度优先用C语言实现深度优先搜索算法。内附完整代码。 大家好,我是贤弟! 一、什么是深度优先搜索? 深度优先搜索算法(Depth-First Search,DFS)是一种常用的图形搜索算法,用于遍历或搜索树或图的数据结构。 它从根节点开始,尽可能深地搜索树的分支,直到达到叶子节点。https://cloud.tencent.com/developer/news/1087237
4.深度优先和广度优先搜索算法DFSBFS下面是深度优先搜索的伪代码实现: procedure DFS(G, v) is label v as discovered for each edge (v, w) in G.adjacentEdges(v) do if vertex w is not labeled as discovered then recursively call DFS(G, w) 二、广度优先搜索 BFS 概述 广度优先搜索(Breadth First Search,BFS)是一种用于遍历图或https://www.jianshu.com/p/6e94f305fbc2
5.二分搜索树深度优先遍历菜鸟教程Java 实例代码 源码包下载:Download src/runoob/binary/Traverse.java 文件代码: packagerunoob.binary; /** * 优先遍历 */ publicclassTraverse<KeyextendsComparable<Key>, Value>{ // 树中的节点为私有的类, 外界不需要了解二分搜索树节点的具体实现 https://www.runoob.com/data-structures/binary-search-traverse.html
6.图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS)深度优先遍历(Depth First Search, 简称 DFS) 广度优先遍历(Breath First Search)它是图论中两种非常重要的算法,广泛应用于拓扑排序、道路搜索(迷宫)、搜索引擎、爬虫等,也经常出现 leetcode,在高频面试题中。 本文将从以下几个方面讲述深度优先遍历和广度优先遍历。相信大家看了肯定会有收获。 https://www.tulingxueyuan.cn/tlzx/jsp/3257.html
7.python底层深度优先python深度优先搜索取出栈内还未出栈的元素,即达到深度优先遍历。 案例实践:利用栈来深度搜索打印出目录结构 程序代码: #__author:"吉**" #date: 2018/10/21 0021 #function: # 深度优先遍历目录层级结构 import os def getAllDirDP(path): stack = [] # 压栈操作,相当于图中的A压入 https://blog.51cto.com/u_16099344/11715159
8.证据计数法在落子类机器博弈中的应用1)前端节点无差别.根据证据计数法的定义,前端节点的值相等时首先选择最左端的节点进行展开.这样的规定,将出现一些不必要的展开,从而浪费时间和内存空间,特别是对深度优先的PN算法的搜索效率影响非常大.文献[9]针对这一缺点进行了改进. 2)占用巨大的内存空间.根据证据计数法的定义,必须要将整个搜索树存放到内存中,这https://xuebao.neu.edu.cn/natural/article/html/2016-8-1070.htm
9.广州市人民政府关于印发广州市国民经济和社会发展第十四个五年当前和今后一个时期,我国发展仍然处于重要战略机遇期,世界百年未有之大变局与中华民族伟大复兴的战略全局深度联动构成广州发展环境的主基调,经济社会发展面临机遇选好用好领军人才和拔尖人才,推进团队带头人全权负责制,赋予更大的用人权、用物权、经费使用权、技术路线决定权、内部机构设置权和人才举荐权,优先保障经费https://www.gz.gov.cn/zfjg/gzsrmzfbgt/qtwj/content/mpost_7287969.html