codeforces #286 div2 C(DP)

2015-01-19 01:23:28

思路:嘛...其实只要发现d的变化范围不超过300(准确来说只要使1+2+3+....+k>30000,k就是范围)就行了。

  用记忆化搜索,其中一个参数是d偏离最开始的值的大小。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <vector>
 6 #include <map>
 7 #include <set>
 8 #include <stack>
 9 #include <queue>
10 #include <string>
11 #include <iostream>
12 #include <algorithm>
13 using namespace std;
14 
15 #define MEM(a,b) memset(a,b,sizeof(a))
16 #define REP(i,n) for(int i=1;i<=(n);++i)
17 #define REV(i,n) for(int i=(n);i>=1;--i)
18 #define FOR(i,a,b) for(int i=(a);i<=(b);++i)
19 #define RFOR(i,a,b) for(int i=(a);i>=(b);--i)
20 #define MP(a,b) make_pair(a,b)
21 
22 typedef long long ll;
23 typedef pair<int,int> pii;
24 const int INF = (1 << 30) - 1;
25 const int maxn = 30010;
26 
27 int n,d,cur,tmax,num[maxn];
28 int dp[maxn][1000];
29 
30 int Dfs(int p,int pre){
31     if(p > tmax) return 0;
32     if(dp[p][pre - d + 400] != -1) return dp[p][pre - d + 400];
33     int res = 0;
34     if(pre > 1) res = max(res,Dfs(p + pre - 1,pre - 1));
35     res = max(res,Dfs(p + pre,pre));
36     res = max(res,Dfs(p + pre + 1,pre + 1));
37     return dp[p][pre - d + 400] = res + num[p];
38 }
39 
40 int main(){
41     int a;
42     MEM(dp,-1);
43     scanf("%d%d",&n,&d);
44     REP(i,n){
45         scanf("%d",&a);
46         num[a]++;
47         tmax = max(tmax,a);
48     }
49     printf("%d\n",Dfs(d,d));
50     return 0;
51 }

 

posted @ 2015-01-19 01:25  Naturain  阅读(112)  评论(0编辑  收藏  举报