搜索是个神奇的东西,分dfs及bfs等(鉴于我后面有个人说不只两种,因此加个“等”),即深度优先搜索和广度优先搜索等,一般来说,深搜要用到递归,而广搜用队列维护,并且一般的一般来说,广搜会比深搜优秀。搜索一般都比较盲目,所以会做很多的无用功,因此数据一般较小,就是这样,概念说不清,看例题吧。
T1
奇怪的电梯
有一种奇怪的电梯,每一层都可以停电梯,但是第i层只能向上或向下走k_i层楼,问从a层到b层至少要按几次电梯。
这道题很经典,用dfs的话,以dfs一条道走到黑的信念,搜起来麻烦,并且估计很有可以RE。那么用bfs搜索,我们以现在在第几层楼为参数,然后分两种情况去搜索,向上或向下,但是在搜索前必须进行判断,不能让它搜出来边界,否则就回不来了。用一个队列存储,将能走到但还未走过的楼层入队,然后再那一层楼向上或向下走k_i层,再次进行上述操作,直到走到目标楼层,当然,也有可能走不到那一层楼,所以我们可以设置一个vis数组标记这个点是否走过,这样不仅可以判断最后能否走到,也可以不走已走过的点。
#include<bits/stdc++.h>
using namespace std;
int t[250],vis[250],q[250],head=1,tail,k[250],a,b,n;
void bfs(int x)
{
int top;
t[a]=0;
vis[a]=1;
q[++tail]=a;
if(x==b)
return;
while(head<=tail)
{
top=q[head++];
vis[top]=1;
if(top+k[top]<=n&&!vis[top+k[top]])//向上走k_i层不超过最高层,且那一层未走过
{
q[++tail]=top+k[top];
vis[top+k[top]]=1;
t[top+k[top]]=t[top]+1;//走到这一层的步数一定是上一层+1步
}
if(top-k[top]>0&&!vis[top-k[top]])//同理,向下走
{
q[++tail]=top-k[top];
vis[top-k[top]]=1;
t[top-k[top]]=t[top]+1;
}
}
}
int main()
{
cin>>n>>a>>b;
for(int i=1;i<=n;i++)
cin>>k[i];
bfs(a);
if(vis[b])//判断是否走到
cout<<t[b]<<endl;
else
cout<<-1<<endl;
return 0;
}
T2
健康的荷斯坦奶牛
农夫知道每种饲料中所包含的牛所需的最低的维他命量是多少。请你帮助农夫喂养他的牛,以保持它们的健康,使喂给牛的饲料的种数最少。 给出牛所需的最低的维他命量,输出喂给牛需要哪些种类的饲料,且所需的饲料剂量最少。(每种饲料最多只能对牛使用一次)
这是dfs,但也可以不用dfs做,如果用dfs做就可以引入一种新的问题,选物品的问题,因为每种饲料只能使用一次,所以每一种饲料都只有选和不选两种情况,如果现在各种维生素已经到达标准,那么可以把这种方案存下来,和以后达到标准的进行比较,选出所需饲料剂最小的输出。
#include<bits/stdc++.h>
using namespace std;
int n,m,a[35],b[35][35],ans=10000000;
int Ans[35],Ans_[35];
int t,s[35]={};
int f()
{
int p=1;
for(int i=1;i<=n;i++)
if (s[i]<a[i])
{
p=0;
break;
}
return p;
}
void dfs(int x)
{
if (t>=ans) return ;
if(f())//判断是否满足条件,若满足就存储下来
{
ans=t;
for(int i=1;i<=t;i++)
Ans[i]=Ans_[i];
return ;
}
if(x==m+1)//如果搜到了m+1种饲料,就只能跳出了,因为已经没有饲料了
{
return ;
}
for(int i=1;i<=n;i++)
s[i]+=b[x][i];//统计各种维生素的量
Ans_[++t]=x;
dfs(x+1);//直接忽略,不选
t--;
for(int i=1;i<=n;i++)
s[i]-=b[x][i];
dfs(x+1);
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
cin>>m;
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
cin>>b[i][j];
dfs(1);//从第一种饲料开始判断
cout<<ans<<' ';
for(int i=1;i<=ans-1;i++)
cout<<Ans[i]<<' ';
cout<<Ans[ans];
return 0;
}