zoukankan      html  css  js  c++  java
  • E

    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,…,a������������x,b,b,…,b����������y,a,a,…,a������������x]. 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].
    View Code

    题意杀我,一定要明白是找到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 }
  • 相关阅读:
    中国SNS用户体验设计分析和互动性浅析
    jQuery的运行机制和设计理念
    Web前端工程师如何给自己定位?
    用户体验这点事儿
    css selection改变文字反选的背景颜色
    HTTP 状态代码
    [翻译]导致网站可用性差的十个最常见问题
    前端开发中的一些用户体验细节
    SQL的行转列问题
    ASP.NET动态添加文本框参考做法
  • 原文地址:https://www.cnblogs.com/yuelian/p/12738614.html
Copyright © 2011-2022 走看看