[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 }

 

posted @ 2017-05-13 20:35  Kirai  阅读(264)  评论(0编辑  收藏  举报