Hdu--5064(DP)

2014-10-15 22:36:29

思路:挺好的一道动规题,需要仔细分析。怒粘一篇std题解。

1003 Find Sequence
首先考虑解的结构一定是C1,C1,,C1,C2,C3,,Cm这种形式,其中满足C1<C2<C3<<Cm
所以对a1,a2,a3,,an去重后从小到大排序得到c1,c2,c3,,cx其中x是sqrt(M)级别的,用DP[i][j]表示以cicj结尾的满足条件的最长序列
首先初值化 DP[i][i]=count(ci)ci在原序列中的个数。
而dp[i][j]=max(dp[k][i] 其中ki还满足cickcjci)+1
这样的复杂度是 O(x^3),在题中x最大为1000级别所以会超时,要使用下面优化
因为 dp[i][j]=max(dp[k][i] 其中ki还满足cickcjci)+1
dp[i][j+1]=max(dp[k][i] 其中ki还满足cickcj+1ci)+1
注意到cj+1>cj 所以满足cickcjci的dp[k][i]必然满足cickcj+1ci因而不必重复计算
即最后复杂度可以为O(x^2).

 1 /*************************************************************************
 2     > File Name: 1003.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com 
 5     > Created Time: Sat 11 Oct 2014 08:42:37 PM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <vector>
13 #include <map>
14 #include <set>
15 #include <queue>
16 #include <iostream>
17 #include <algorithm>
18 using namespace std;
19 #define lp (p << 1)
20 #define rp (p << 1|1)
21 #define getmid(l,r) (l + (r - l) / 2)
22 #define MP(a,b) make_pair(a,b)
23 typedef long long ll;
24 const int INF = 1 << 30;
25 const int maxn = 1 << 12;
26 
27 int val[1 << 22],c[maxn],n,m,t;
28 int dp[maxn][maxn];
29 
30 int main(){
31     scanf("%d",&t);
32     while(t--){
33         memset(dp,0,sizeof(dp));
34         scanf("%d%d",&n,&m);
35         for(int i = 1; i <= n; ++i) scanf("%d",&val[i]);
36         sort(val + 1,val + n + 1);
37         int cur = 1;
38         c[cur] = 1;
39         for(int i = 2; i <= n; ++i){
40             if(val[i] == val[cur]) ++c[cur];
41             else{
42                 val[++cur] = val[i];
43                 c[cur] = 1;
44             }
45         }
46         int ans = 0;
47         for(int i = 1; i <= cur; ++i) dp[i][i] = c[i];
48         for(int i = 1; i <= cur; ++i){
49             int k = i,tmax;
50             tmax = dp[i][i];
51             ans = max(ans,tmax);
52             for(int j = i + 1; j <= cur; ++j){
53                 for(; k > 0 && val[i] - val[k] <= val[j] - val[i]; --k){
54                     tmax = max(tmax,dp[k][i] + 1);
55                 }
56                 dp[i][j] = tmax;
57                 ans = max(ans,tmax);
58             }
59         }
60         printf("%d\n",ans);
61     }
62     return 0;
63 }

 

 
posted @ 2014-10-15 22:38  Naturain  阅读(111)  评论(0)    收藏  举报