http://acm.hdu.edu.cn/showproblem.php?pid=4512
题目:腾讯第二届第二场的比赛,我这种若菜比赛时,就没做出来,也是赛后听人指导才做出的哦!!!
吉哥这几天对队形比较感兴趣。
有一天,有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]。
现在吉哥想知道:最多能选出多少人组成完美队形?
思路:转化为求公共最长递增序列
所以首先要会lcis,才能做出这到题
代码:
1 #include <cstdio> 2 #include <cstring> 3 int c[201],a[201],b[201],f[201][201]; 4 int main() 5 { 6 int t; 7 scanf("%d",&t); 8 while(t --) 9 { 10 int n; 11 scanf("%d",&n); 12 for(int i = 1;i <= n;i ++) 13 scanf("%d",&c[i]); 14 if(n == 1){puts("1");continue;} 15 int v1,v2,max = 0; 16 for(int i = 1;i < n;i ++) 17 { 18 memset(f,0,sizeof(f)); 19 v1 = 1;v2 = 1; 20 for(int j = 1;j <= i;j ++) 21 a[v1 ++] = c[j]; 22 for(int j = n;j > i;j --) 23 b[v2 ++] = c[j]; 24 int w1,w2,m = 0,mm = 0,sum1; 25 for(int p = 1;p < v1;p ++) 26 { 27 int max1 = 0; 28 for(int q = 1;q < v2;q ++) 29 { 30 f[p][q] = f[p - 1][q]; 31 if(a[p] > b[q] && max1 < f[p - 1][q]) max1 = f[p - 1][q]; 32 if(a[p] == b[q]) 33 { 34 f[p][q] = max1 + 1; 35 if(f[p][q] > mm) 36 { 37 mm = f[p][q]; 38 w1 = p; 39 w2 = q; 40 m = a[p]; 41 } 42 } 43 44 } 45 } 46 if(mm == 0) sum1 = 1; 47 else 48 { 49 int flag = 0; 50 for(int p = w1 + 1;p < v1;p ++) 51 if(a[p] > m) 52 { 53 flag = 1; 54 break; 55 } 56 for(int p = w2 + 1;p < v2;p ++) 57 if(b[p] > m) 58 { 59 flag = 1; 60 break; 61 } 62 if(flag) 63 sum1 = 1 + mm * 2; 64 else 65 sum1 = mm * 2; 66 } 67 if(sum1 > max) 68 max = sum1; 69 } 70 printf("%d\n",max); 71 } 72 return 0; 73 }