题目:https://www.luogu.com.cn/problem/P1135
思路:
直接搜,没越界就搜
但是注意!!!这次的dfs需要剪枝技巧,否则时间上过不去
剪枝1:对当前答案进行判断
如果已经达到目标楼层,再用这层递归搜下去只会徒增搜索时间而不会改变结果
所以在判断完是不是最优解之后,直接用return扔掉
如果当前的按按钮次数已经超过了当前的最优解
那还搜个屁啊,搜了也没有,return丢掉得了
剪枝2:定义一个访问数组v
如果在这个地方搜完之后兜兜转转又回到了这个楼层,那还要分时间出来再走一遍已经走过的路
“何の意味もない”
还搜什么,扔掉得了
#include<bits/stdc++.h>
using namespace std;
int n,a,b,k[201],i,v[201],ans=0x3f3f3f3f;
//对于ans,找到最小值,ans就要尽量大一些
void dfs(int h,int sum){
//h为当前楼层,sum为按按钮次数
if(h==b){//找到目标
ans=min(ans,sum);//对比一下看能不能用,毕竟我们找的是最小值
return;//剪枝
}
if(sum>ans){//比原来的最小值大,证明不是最优解
return;//那还搜个屁
}
v[h]=1;//标记
if(h+k[h]<=n&&!v[h+k[h]]){//没越界
dfs(h+k[h],sum+1);//开搜
}
if(h-k[h]>=1&&!v[h-k[h]]){//没越界
dfs(h-k[h],sum+1);//开搜
}
v[h]=0;//回溯
}
int main(){
scanf("%d%d%d",&n,&a,&b);
for(i=1;i<=n;++i){
scanf("%d",&k[i]);
}
memset(v,0,sizeof(v));//记得调零
v[a]=1;//标记
dfs(a,0);
if(ans!=0x3f3f3f3f){//如果ans已经被改过了,证明此问题有解
printf("%d",ans);//输出
}
else{//否则就是无解
printf("-1");//那还玩个屁
}
return 0;
}
题目总结:就是一个坐电梯按按钮的事
dfs可以,但是需要多次剪枝
建议使用bfs(虽然我不会)