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]。
現在吉哥想知道:最多能選出多少人組成完美隊形?
Input 第一行輸入T,表示總共有T組資料(T <= 20);
每組資料先輸入原先隊形的人數n(1<=n <= 200),接下來一行輸入n個整數,表示按順序從左至右原先隊形位置站的人的身高(50 <= h <= 250,不排除特別矮小和高大的)。
Output 請輸出能組成完美隊形的最多人數,每組資料輸出佔一行。
Sample Input
2351 52 51451 52 52 51
思路:很容易就想到了將原串翻轉再求LICS,
#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;int n,a[205],b[205],dp[205];int LICS(){ int MAX,i,j,k; memset(dp,0,sizeof(dp)); MAX = 0; for(i = 1; i<=n; i++) { k = 0; for(j = 1; j<=n-i+1; j++) { if(a[i] == b[j]) { if(j!=(n-i+1))//沒與自身匹配 { if(dp[j]<(dp[k]+2))//長度加2 dp[j] = dp[k]+2; } else//與自身匹配了 { if(dp[j]<(dp[k]+1))//自身所以只加1長度 dp[j] = dp[k]+1; } } else if(a[i]>b[j] && dp[k]<dp[j]) k = j; if(MAX<dp[j]) MAX = dp[j]; } } return MAX;}int main(){ int t,i; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i = 1; i<=n; i++) scanf("%d",&a[i]); for(i = 1; i<=n; i++) b[i] = a[n-i+1]; printf("%d\n",LICS()); } return 0;}