搜索专题(dfs and bfs)

搜索,顾名思义,就是对某样事物进行寻找。好了我就不多废话了。搜索有多种形式,常见的dfs(深度优先搜索)和bfs(广度优先搜索)等等,这也就是今天的主要内容:

1.dfs:深度优先搜素,就相当于你去逛街,有很多条街相通,你选择先走任意一条街,如果没有自己想要去的店,那么回到上一个路口,再选择一条没走过的路继续走到底。如:因式分解,即输入n,求将n因式分解的总方案数。

首先,看到这题,我首先想到的是用递归去求n的各个因式,但当n足够大时,这种递归写法很显然会超时,这时就要进行一定的优化了,考虑到n的因式可能还有因式,就不难想到,n的因式的总方案数也一定包括了n的因式的因式。这么说有点绕口又有点难懂,那么具体看看代码:

#include
using namespace std;
long long n,a[15000],b[15000],ghj=1;
int main()
{
b[1]=1;
cin>>n;
for(int i=1;i*i<=n;i++)
{
if(n%i==0)
{
a[ghj++]=i;//n的小于根号n的约数; 
if(i*i!=n)
{
a[ghj++]=n/i;//n的大于根号n的约数; 
}
}
}
sort(a+1,a+ghj);
for(int i=1;i

看了这个,就可以很容易的想到n的因式之间的关系(虽然我没用递归(*^__^*) 嘻嘻),知道了他们之间的关系后,就不难求出n的方案数了。(不得不说代码是真的又臭又长)

2.dfs:广度优先搜索,就好比我现在要去洗手间,我要找一条最近的路,假设我有很多分身,那么分身们向不同方向走去,在时间相同的情况下,第一个到达洗手间的分身所走的路线一定是最短的(速度也相同)。典型题如:奇怪的电梯,从a楼到b楼,电梯在每个楼层所可以上升或下降的层数不同,求出最少次数。

看完题目,我的第一反应就是模拟一下电梯的(鬼畜)移动,在既可上升又可下降时,用bfs进行搜索,具体代码如下:

#include
using namespace std;
int n,a,b,k[201]={},here,m,ans,minnest=1000000;
bool look[201]={};//标记,指该电梯是否到达过
void bfs(int here,int y){
 if(y>=minnest) return;//如果比已有方案的次数要多,显然不是最优方案,直接返回
 if(here==b){//如果到达了b层
     minnest=min(minnest,y);//那么比较它的次数与原有方案的次数
     return;
 }
 if(here-k[here]>0&&look[here-k[here]]==false)//第一种情况:如果可以下降且下降后到达的楼层未曾到达过
 {
  look[here-k[here]]=true;//标记为此楼层已到达过
  bfs(here-k[here],y+1);//递归,继续移动
  look[here-k[here]]=false;//递归完毕后将此楼层标记为未到达过(因为仅当此时电梯选择下降时才到达过次楼层)
 }
 if(here+k[here]<=n&&look[here+k[here]]==false)//第二种情况:如果可以上升且上升后到达的楼层未曾到达过
 {
  look[here-k[here]]=true;
  bfs(here+k[here],y+1);
     look[here-k[here]]=false;//同上
 } 
}
int main()
{
 cin>>n>>a>>b;
 for(int i=1;i<=n;i++)
 {
     cin>>k[i];
 }
 bfs(a,0);
 if(minnest==1000000) cout<<"-1"<

整个也就是个类似模拟,在电梯可以进行多种(两种)情况的移动时分别模拟,最后得出最少次数。(仍然是又臭又长)

 



你可能感兴趣的:(专题)