hdu 4512 吉哥系列故事——完美队形I(最长公共上升子序列)

Problem Description
  吉哥这几天对队形比较感兴趣。
  有一天,有n个人按顺序站在他的面前,他们的身高分别是h[1], h[2] ... h[n],吉哥希望从中挑出一些人,让这些人形成一个新的队形,新的队形若满足以下三点要求,则称之为完美队形:
  
  1、挑出的人保持他们在原队形的相对顺序不变;
  2、左右对称,假设有m个人形成新的队形,则第1个人和第m个人身高相同,第2个人和第m-1个人身高相同,依此类推,当然,如果m是奇数,中间那个人可以任意;
  3、从左到中间那个人,身高需保证递增,如果用H表示新队形的高度,则H[1] < H[2] < H[3] .... < H[mid]。

  现在吉哥想知道:最多能选出多少人组成完美队形?
 
做法:枚举断点,分成两个段,求最长公共上升子序列。
View Code
 1  /*
 2  Author:Zhaofa Fang
 3  Lang:C++
 4  */
 5  #include <cstdio>
 6  #include <cstdlib>
 7  #include <sstream>
 8  #include <iostream>
 9  #include <cmath>
10  #include <cstring>
11  #include <algorithm>
12  #include <string>
13  #include <utility>
14  #include <vector>
15  #include <queue>
16  #include <stack>
17  #include <map>
18  #include <set>
19  using namespace std;
20 
21  typedef long long ll;
22  #define DEBUG(x) cout<< #x << ':' << x << endl
23 #define REP(i,n) for(int i=0;i < (n);i++)
24 #define REPD(i,n) for(int i=(n-1);i >= 0;i--)
25 #define FOR(i,s,t) for(int i = (s);i <= (t);i++)
26 #define FORD(i,s,t) for(int i = (s);i >= (t);i--)
27 #define PII pair<int,int>
28 #define PB push_back
29 #define MP make_pair
30 #define ft first
31 #define sd second
32 #define lowbit(x) (x&(-x))
33 #define INF (1<<30)
34 
35 int dp[205],h[205];
36 int f[205][205];
37 int a[205],b[205];
38 int calc(int n,int m){
39     memset(dp,0,sizeof(dp));
40     FOR(i,1,n){
41         int k = 0;
42         FOR(kk,1,m)f[i][kk] = f[i-1][kk];
43 
44         FOR(j,1,m){
45             if(b[j]<a[i] && dp[k]<dp[j])k = j;
46             if(b[j]==a[i]&&dp[k]+1>dp[j]){
47                 dp[j] = dp[k] + 1;
48                 f[i][j] = i*(m+1)+k;
49             }
50         }
51     }
52     int ma = 1;
53     FOR(j,1,m)
54         if(dp[ma]<dp[j])ma = j;
55     return dp[ma];
56 }
57  int main()
58 {
59      //freopen("in","r",stdin);
60      int T;
61      scanf("%d",&T);
62      while(T--){
63         int n;
64         scanf("%d",&n);
65         FOR(i,1,n)scanf("%d",&h[i]);
66         int ans = -1;
67         FOR(i,1,n){
68             int tmp1,tmp2;
69             FOR(j,1,i)a[j] = h[j];
70             FORD(j,n,i+1)b[n+1-j] = h[j];
71             tmp1 = calc(i,n-i);
72 
73             b[n-i+1] = h[i];
74             tmp2 = calc(i,n-i+1);
75             if(tmp2>tmp1)ans = max(ans,tmp1*2+1);
76             else ans = max(ans,tmp1*2);
77         }
78         printf("%d\n",ans);
79      }
80      return 0;
81  }

 

posted @ 2013-03-23 12:24  發_  阅读(750)  评论(0编辑  收藏  举报