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]。
现在吉哥想知道:最多能选出多少人组成完美队形?
有一天,有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 }