深搜与栈浅谈

本文介绍了深度优先搜索(DFS)算法,包括其基本思想和应用。文章通过自然数拆分问题和跑步问题两个实例,详细阐述了如何利用DFS解决问题,并提到了栈在DFS中的作用,帮助读者深入理解DFS及其在实际问题中的运用。
摘要由CSDN通过智能技术生成

一、引入

搜索分为两大类——深度优先搜索算法和广度优先搜索算法。这里我给大家介绍一下深度优先搜索算法(简称深搜)。它通过递归(即函数调用自身)的方式,一步步向答案逼近,最终得出正确答案。但值得注意的是,这种算法未经剪枝优化会特别慢,很容易超时。深搜被广泛应用到多个领域。在比赛中,深搜的思路也是特别好想的,在想不出别的思路时可以用深搜骗点分。剪枝什么的暂时先不讲,下面我们先介绍一下栈,再简介一下深搜模板,最后通过几道例题讲解一下。

二、栈

栈(stack)是一种常见的数据结构,一般我们可以用数组实现。我们把栈里面的每一个元素就是一块板子。我们要把板子堆起来,可以想象,我们只能把最新那块板子放在之前最上面那块板子之上。同理,我们一次只能取走最上面的那块板子。假如我们把所有板子放完后再逐个拿出,不难发现最后一个放上去的板子第一个被拿出;第一个被放上去的板子最后一个拿出。因此,栈也有“先进后出表”之称。我们用一个数组stk[]表示栈,并用一个变量top记录栈顶(即最上面的元素)的位置。现在要加入一个元素x,我们只要将top加一,在给栈顶赋值x即可,也就是说stk[++top]=x。弹出栈顶元素只需要将top减一就行了,即top-=1

三、深度优先搜索算法

下面简介一下深搜的主要思想。不难发现,对于每一个决策点,到达终点的方案数唯一。在当前遍历到的决策点,我们一边枚举下一步走法,一边直接走下一步,到达一个里终点更近的子决策点。在新的决策点,我们采取同样的方式,从而一步步向终点靠近,最终到达终点或终点附近,直接返回一个确定的值。那么每一个决策点的可行方案应该为所有子决策点的可行方案(加上当前走法)。
下面展示一段深搜的伪代码:

int dfs(int x){
   
	if(x为终点){
   
		统计(输出);
		return;
	}
	for(y为x的子决策点){
   
		dfs(y);
		统计答案;
	}
	return;
}

若果决策点没有重复,我们发现所有决策点构成一棵树,否则构成一张有向无环图。对于后面的情况,我们一般采用记忆化搜索的方式进行优化,也就是说,在到达一个新决策点时,我们用一个数组记录它,当再次到达同一个决策点时,只需用O(1)的复杂度返回就行了。
事实上每当到枚举每一个子决策点时,就相当于把新的决策点放入栈顶。当访问完它所引出的所有决策点后便能把他从栈顶取出,否则继续找出它所引出的决策点加入栈顶。在它所有引出的决策点求解完之前,它始终不在栈顶,便无法取出即无法求解。一开始栈中只有一个元素即起点,当求完所有决策点时,我们便发现栈空了。也就是说,每一次深搜等价于一个栈

四、经典例题

下面我们通过具体问题更深入地了解深搜

1.自然数的拆分问题

任何一个大于1的自然数n,总可以拆分成若干个小于n的正整数之和。现在给你一个自然数n,要求你求出n的拆分

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值