深搜(总结+例题)

所谓深搜(也叫回溯法)就是采用的是“一直往下走,走不通了就掉头,换一条路再往下走

总结来说就是递归的枚举

深度优先搜索的实质就是穷举,按照一定的顺序和规则不断地去尝试,直到找到问题的解。

对于一个问题的第一个状态叫做初始状态,最后要求的状态叫做目的状态

在搜索的过程中,对当前状态进行检测,如果当前状态满足目的状态,那么这个当前状态就是结果之一。

为什么要取消标记:

深搜搜到底以后,结束dfs(),该点不会继续被他的父亲节点再次搜到,即便已经取消标记,因为有一个for循环,下一次会再次访问与它处于同一级的其他节点

模板:

void dfs(int x,int y){
	if(vis[x][y])
	    return ;
	for(int i=0;i<4;i++){//向各个方向 
		int fx=x+mov[i][0];
		int fy=y+mov[i][1];
		if(fx<0||fy<0||fx>=tmp1||fy>=tmp2)//不要越界
		    continue;
		vis[fx][fy]=1;//标记 
		dfs(fx,fy);
		vis[fx][fy]=0;//取消标记 
	}
}

深搜的特点:

(1)深度优先搜索法有递归以及非递归两种设计方法。一般的,当搜索深度较小、问题递归方式比较明显时,用递归方法设计好,它可以使得程序结构更简捷易懂。当数据量较大时,由于系统堆栈容量的限制,递归容易产生溢出,用非递归方法设计比较好。

(2)深度优先搜索方法有广义和狭义两种理解。广义的理解是,只要最新产生的结点(即深度最大的结点)先进行扩展的方法,就称为深度优先搜索方法。在这种理解情况下,深度优先搜索算法有全部保留和不全部保留产生的结点的两种情况。而狭义的理解是,仅仅只保留全部产生结点的算法。本书取前一种广义的理解。不保留全部结点的算法属于一般的回溯算法范畴。保留全部结点的算法,实际上是在数据库中产生一个结点之间的搜索树,因此也属于图搜索算法的范畴。

(3)不保留全部结点的深度优先搜索法,由于把扩展望的结点从数据库中弹出删除,这样,一般在数据库中存储的结点数就是深度值,因此它占用的空间较少,所以,当搜索树的结点较多,用其他方法易产生内存溢出时,深度优先搜索不失为一种有效的算法。
 (4)不一定会得到最优解,这个时候需要修改原算法:把原输出过程的地方改为记录过程,即记录达到当前目标的路径和相应的路程值,并与前面已记录的值进行比较,保留其中最优的,等全部搜索完成后,才把保留的最优解输出。 

优化的方式(剪枝):
1.优化搜索顺序:产生不同的搜索树形态,规模就会有所不同

2.排除等效冗余:排除产生相等结果的可能

3.可行性剪枝:排除那些已经无论如何都无法达到递归边界的分支

4.最优性剪枝:当前花费已经超过了当前得到的最优解

5.记忆化

其他的拓展:
1.迭代加深:用在可以确保答案在一个比较浅层的节点(每次搜索的时候,限定层级)

2.双向搜索(待补充)

例题:

1.蜘蛛牌

2.符号三角形

3.Oil Deposits(判断联通体)

4.Rescue (解救小伙伴)

5.Prime Ring Problem(深搜+素数判断)

6.小猫爬山

 

 

 

  • 19
    点赞
  • 91
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值