题目链接:http://codeforces.com/problemset/problem/797/E
题意:给定一个数组a[n],q次询问,给定p、k,每次使p = p + a[p] + k,回答p超过n时的次数。n, q 小于 100000,p、k小于n,a[i] 小于n。
题解:暴力显然过不了极端情况,考虑到在k较大时,暴力跑时次数会很少,则对k进行分类,大于MAXK时直接暴力,小于时记忆化即可。
代码:
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <stack>
#include <set>
#include <queue>
#include <functional>
#include <map>
#include <bitset>
#define INF 0x7fffffff
#define REP(i,j,k) for(int i = j;i <= k;i++)
#define squr(x) (x) * (x)
#define lowbit(x) (x&(-x))
#define getint(x) scanf("%d", &(x))
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
const int MAXN = 1e5 + 10;
const int MAXK = 200;
int n, a[MAXN], q, p, k;
int dp[MAXN][MAXK];
int ans;
int dfs(int x) {
if (x > n) {
return 0;
}
if (dp[x][k] != 0) {
return dp[x][k];
}
return dp[x][k] = 1 + dfs(x + a[x] + k);
}
int main(int argc, const char * argv[]) {
getint(n);
REP(i, 1, n) {
getint(a[i]);
}
getint(q);
REP(i, 1, q) {
ans = 0;
getint(p);
getint(k);
if (k >= MAXK) {
while (p <= n) {
p = p + k + a[p];
ans++;
}
printf("%d\n", ans);
} else {
printf("%d\n", dfs(p));
}
}
return 0;
}