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 }

 

 

转载于:https://www.cnblogs.com/naturepengchen/articles/4027630.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值