You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
|
#include<bits/stdc++.h>
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
/**
|
|
|
|
|
动态规划,设f[i]为到第i层的按键最少次数
|
|
|
|
|
*/
|
|
|
|
|
const int N = 100010;
|
|
|
|
|
const int INF = 0x3f3f3f3f;
|
|
|
|
|
int n; //n层楼
|
|
|
|
|
int a; //从a层
|
|
|
|
|
int B; //到b层
|
|
|
|
|
int K[N]; //k数组表示第一层出现的数字k[i]
|
|
|
|
|
int f[N]; //设f[i]为到第i层的按键次数最少(这个定义非常妙,最终的结果保存在f[b]里,
|
|
|
|
|
// 而f[b]是通过f[i]推导出来的)
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
int main() {
|
|
|
|
|
//初始化为INF
|
|
|
|
|
memset(f, 0x3f, sizeof f);
|
|
|
|
|
|
|
|
|
|
//读入
|
|
|
|
|
cin >> n >> a >> b;
|
|
|
|
|
for (int i = 1; i <= n; i++) cin >> k[i];
|
|
|
|
|
|
|
|
|
|
//base case,边界条件
|
|
|
|
|
f[a] = 0;
|
|
|
|
|
/******这个变量+循环尝试的方法很重要啊!******/
|
|
|
|
|
bool isLoop = true; //是否需要继续尝试,当本次操作没有修改时,就不需要继续操作了,
|
|
|
|
|
// 因为这就是无法再继续更新的意思。
|
|
|
|
|
while (isLoop) { //用这个循环控制,是最好理解的,而不是网上说的什么n次,那个n次是玄学,非科学
|
|
|
|
|
isLoop = false;
|
|
|
|
|
for (int i = 1; i <= n; i++) { //讨论在每一层楼时的情况
|
|
|
|
|
int x = i - k[i]; //下楼
|
|
|
|
|
int y = i + k[i]; //上楼
|
|
|
|
|
//如果下楼的步数优于现有解,那么优化掉
|
|
|
|
|
if (f[x] > f[i] + 1 && x >= 1) f[x] = f[i] + 1, isLoop = true;
|
|
|
|
|
//如果上楼的步数优于现有解,那么优化掉
|
|
|
|
|
if (f[y] > f[i] + 1 && y <= n) f[y] = f[i] + 1, isLoop = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//还是初始值的,表示无法到达!
|
|
|
|
|
if (f[b] == INF) cout << -1;
|
|
|
|
|
else cout << f[b]; // f[b]里保存的是结果
|
|
|
|
|
return 0;
|
|
|
|
|
}
|