[CF797E] Array Queries(记忆化搜索,暴力)
题目链接:http://codeforces.com/contest/797/problem/E
题意:给n个数,q次询问。
每次询问给两个数p k,操作是p=ap+k,问多少次可以让p>n。
直接暴力会TLE,设计dp(i,j)为当p为i时,k为j时的最少步骤,可以这样更新来:dp(i+a(i)+j, j)=dp(i,j)+1。
显然n这么大,数组开不下。
这样,假如k很大的时候,p+ap+k是很容易超过n的,所以设定一个阈值,在这个阈值以外用暴力来做。其余的dp。
假如k大于500,那么暴力,小于500则dp。记忆化好写很多。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 100100; 5 int n, q; 6 int a[maxn], dp[maxn][500]; 7 int p, k; 8 9 int dfs(int p) { 10 if(p > n) return 0; 11 if(~dp[p][k]) return dp[p][k]; 12 return dp[p][k] = dfs(p+a[p]+k) + 1; 13 } 14 15 int main() { 16 // freopen("in", "r", stdin); 17 while(~scanf("%d",&n)) { 18 for(int i = 1; i <= n; i++) scanf("%d", &a[i]); 19 memset(dp, -1, sizeof(dp)); 20 scanf("%d", &q); 21 while(q--) { 22 scanf("%d%d",&p,&k); 23 if(k > 500) { 24 int ret = 0; 25 while(p <= n) { 26 p = p + a[p] + k; 27 ret++; 28 } 29 printf("%d\n", ret); 30 } 31 else printf("%d\n", dfs(p)); 32 } 33 } 34 return 0; 35 }