The only difference between easy and hard versions is constraints. You are given a sequence a consisting of n positive integers. Let's define a three blocks palindrome as the sequence, consisting of at most two distinct elements (let these elements are a and b, a can be equal b) and is as follows: [a,a,…,ax,b,b,…,by,a,a,…,ax]. There x,y are integers greater than or equal to 0. For example, sequences [], [2], [1,1], [1,2,1], [1,2,2,1] and [1,1,2,1,1] are three block palindromes but [1,2,3,2,1], [1,2,1,2,1] and [1,2] are not. Your task is to choose the maximum by length subsequence of a that is a three blocks palindrome. You have to answer t independent test cases. Recall that the sequence t is a a subsequence of the sequence s if t can be derived from s by removing zero or more elements without changing the order of the remaining elements. For example, if s=[1,2,1,3,1,2,1], then possible subsequences are: [1,1,1,1], [3] and [1,2,1,3,1,2,1], but not [3,2,3] and [1,1,1,1,2].
题意杀我,一定要明白是找到aaabbbaaa这样的回文串,不是普通的回文串,而且子序列的相对位置不可以变,可是明白了题意之后我满脑子都是2^n的算法,显然是不现实的。借用sc学长的题解做法:我们使用三重循环:第一重枚举a是什么,第二重枚举取多少个a,第三种枚举b取什么。这样的话,我们知道,取同样多的a,中间的区间越大,b的个数可能就越多,所以我们取前x个a和后x个a,在这中间找b,由此就有了一个优化:我们记录每一个数出现的所有位置,也记录每一个数在每一个位置出现的前缀和。
1 #include<algorithm> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdio> 5 #include<vector> 6 using namespace std; 7 const int maxn=2e3+5; 8 int t; 9 int n; 10 int a[maxn]; 11 int ans; 12 int s[maxn][30]; 13 vector<int>v[30]; 14 int main() 15 { 16 scanf("%d",&t); 17 while(t--) 18 { 19 scanf("%d",&n); 20 memset(s,0,sizeof(s)); 21 ans=0; 22 for(int i=0;i<30;++i)v[i].clear(); 23 for(int i=1;i<=n;++i) 24 { 25 scanf("%d",&a[i]),v[a[i]].push_back(i); 26 for(int j=1;j<=26;++j) 27 s[i][j]=s[i-1][j]; 28 s[i][a[i]]++;//前缀和 29 } 30 for(int i=1;i<=26;++i) 31 { 32 ans=max(ans,s[n][i]); 33 int hal=(s[n][i]>>1); 34 for(int j=1;j<=hal;++j)//枚举取多少个a 35 { 36 int l=v[i][j-1]+1,r=v[i][s[n][i]-j]-1; 37 if(r>=l) 38 { 39 for(int k=1;k<=26;++k) 40 { 41 ans=max(ans,2*j+s[r][k]-s[l-1][k]); 42 } 43 } 44 } 45 } 46 cout<<ans<<endl; 47 } 48 return 0; 49 }
知世故而不世故,处江湖而远江湖,才是最成熟的善良