题目大意:
有一个电梯,电梯每层可以上或下Ai层,只要上或者下Ai层是合理的
问从A楼层到B楼层最少需要几步。若到达不了则输出-1
解题思路:
这里有一个难点,就是怎么知道产生了循环比如 1->3->5 然后 5->1,产生了这种循环。
所以,我们可以考虑使用回溯。每次走到规定楼层,我们打个标记,以后不能再走。
但是这种回溯最后会T,所以我们考虑加入DP,DP的状态[level][id],level表明现在处于哪一个楼层,id表示我们递归到第几层。
所以memo[level][id] = min(memo[上楼][id+1] ,memo[下楼][id+1])
#include <bits/stdc++.h>
#define int long long
#define INF 0x3f3f3f3f
using namespace std;
int n,a,b;
const int MAXN=200+10l;
bitset<300> flag;
vector<int> arrmv;
int memo[MAXN][MAXN];
int dfs(int level,int id){
if(level==b)return 0;
if(memo[level][id]!=-1)return memo[level][id];
int lf=INF;
if(arrmv[level-1]+level<=n)
if( flag[arrmv[level-1]+level]==0){
flag[arrmv[level-1]+level]=1;
lf=1+dfs(arrmv[level-1]+level,id+1);
flag[arrmv[level-1]+level]=0;
}
int rg=INF;
if(level-arrmv[level-1]>=1 ){
if(flag[level-arrmv[level-1]]==0){
flag[level-arrmv[level-1]]=1;
rg=1+dfs(level-arrmv[level-1],id+1);
flag[level-arrmv[level-1]]=0;
}
}
return memo[level][id]=min(lf,rg);
}
int32_t main(){
cin>>n>>a>>b;
for(int i=0;i<n;i++){
int t;cin>>t;
arrmv.push_back(t);
}
flag[a]=1;
memset(memo,-1,sizeof(memo));
int ans=dfs(a,0);
if(ans>=INF)cout<<-1<<endl;
else cout<<ans<<endl;
return 0;
}