【学习笔记】dfs|bfs|A*|IDA*|IDDFS 搜索杂烩

前排简介。

什么是dfs?

dfs为深度优先搜索的简称,一种暴力求解的方式,当然有很多的玄学优化,我也略会一些。

什么是bfs?

bfs为宽度优先搜索的简称,当然有人也称之为“广度优先搜索”,一个算法。个人认为要比dfs难入门一些。

暂时先介绍这两种搜索。

(链接摘自百度百科)

dfs的计算过程:
1.确定“位置” ,写过全排列的同学应该深有体会。说的专业一点,就是现在所在的状态。例如走迷宫,状态就是当前走到的位置,用 ( x , y ) (x,y) 表示状态。走迷宫嘛,自然是珂以通向四个方向,即在不越界的情况下,珂以从 ( x , y ) (x,y) 走到 ( x , y + 1 ) , ( x , y 1 ) , ( x 1 , y ) , ( x + 1 , y ) (x,y+1),(x,y-1),(x-1,y),(x+1,y) ,这一步我一般称为确定转移的状态,或者说找珂以转移的状态。越界啥的处理既珂,瞎搞,找到终点,即 ( x = n , y = n ) (x=n,y=n) 的状态,结束。然后你会发现有了这些还不够啊,还要些啥呢?你可能觉得上面的已经够充分了。那么我问你一个问题:

比如我们现在在的这个点为 ( s , t ) (s,t) ,然后根据上面的步骤移动到 ( s , t + 1 ) (s,t+1) (没有越界的情况下),然后到了 ( s , t + 1 ) (s,t+1) 的地方又珂以转到 ( s , t ) (s,t) ,就这样一直转。。。爆栈,0分。
所以,珂以发现,访问过的地方不珂以访问了(只针对这一题,其他题还要根据具体的题意设定)。完美解决了上面的情况。
我们现在求它珂不珂以从 ( 1 , 1 ) (1,1) 走到终点 ( n , n ) (n,n) ,代码如下:

bool can=false;
int h[5]={0,-1,1,0,0};
int l[5]={0,0,0,-1,1};
//转移的四种方式
void js(int x,int y) 
{
	if(can) return ; // 这一步是防止在已经到达的情况下还会多算浪费时间,所以果断return
	if(x==n&&y==n)  //到达了终点
	{
	    can=1;
	    return ;
	}
	vis[x][y]=1; //访问过
	for(int i=1;i<=4;i++) 
	{
		int wx=x+h[i],wy=y+l[i]; //转移的状态
		if(wx>=1&&wx<=n&&wy>=1&&wy<=n&&!vis[wx][wy]) 
		{
			js(wx,wy) ; //成功转移!
		}
	}
	vis[x][y]=0; //回溯状态,以(x,y)为根的解答树部分已经全部计算完毕,为保证上面的状态还能经过此点,就是要寻找多种路径,必须还原。理解不了的话就当板子用吧
	return;
}
if(can) cout"Yes\n";
else cout<<"No\n";

这种题烂大街,随便一个OJ搜一下迷宫题应该都有(但有的是求最短路,用dfs可能会卡掉)
最短路的话自己写一下了,反正又不难。

记忆化:
就是把状态当前的解求出来存在数组里,如果下次还要访问到这个状态的话直接返回值,省掉了计算,经典题fib数列。
总结:
Z表示当前状态,Z’表示转移的状态
C a n ( Z ) Can(Z') 表示Z’是否合法。
i f ( Z = a n s ) r e t u r n if(Z=ans) return
n o w now Z Z Z C a n ( Z ) \to Z'|Can(Z')

挖坑待填

发布了24 篇原创文章 · 获赞 32 · 访问量 3789

猜你喜欢

转载自blog.csdn.net/woshidalaocxy/article/details/104867881