前排简介。
什么是dfs?
dfs为深度优先搜索的简称,一种暴力求解的方式,当然有很多的玄学优化,我也略会一些。
什么是bfs?
bfs为宽度优先搜索的简称,当然有人也称之为“广度优先搜索”,一个算法。个人认为要比dfs难入门一些。
暂时先介绍这两种搜索。
(链接摘自百度百科)
dfs的计算过程:
1.确定“位置” ,写过全排列的同学应该深有体会。说的专业一点,就是现在所在的状态。例如走迷宫,状态就是当前走到的位置,用
表示状态。走迷宫嘛,自然是珂以通向四个方向,即在不越界的情况下,珂以从
走到
,这一步我一般称为确定转移的状态,或者说找珂以转移的状态。越界啥的处理既珂,瞎搞,找到终点,即
的状态,结束。然后你会发现有了这些还不够啊,还要些啥呢?你可能觉得上面的已经够充分了。那么我问你一个问题:
比如我们现在在的这个点为
,然后根据上面的步骤移动到
(没有越界的情况下),然后到了
的地方又珂以转到
,就这样一直转。。。爆栈,0分。
所以,珂以发现,访问过的地方不珂以访问了(只针对这一题,其他题还要根据具体的题意设定)。完美解决了上面的情况。
我们现在求它珂不珂以从
走到终点
,代码如下:
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’表示转移的状态
表示Z’是否合法。
挖坑待填