可恶的题面,又得帮你们翻译下,英语不好打这个贼吃亏。
题意:
n个整数a1,a2…an (1<= a <=200), 问一个序列:第一部分全是x,第二部分全
都是y,第三部分全都是x, 也就是整个这个序列的最多2种数字,(x和y可能相等),第三部分和第一部分数量相等,每个部分的数量>=0.
$ 其实直接看这里:,大概就懂什么意思了,
思路:
这题有E1和E2,然后乍一看,基本上觉得是 E1 是一个暴力,E2就应该要用一些小技巧和算法了,但仔细观察,a 的数据范围才200,然后 n是2e5,那我们想一下枚举1-200 每个数字的两边最大,再找中间的最大,不就可以了. 其实 还挺简单的。
- tnnd, 清空vector,就会T, 直接放在函数里面重新定义,但是我的编译器 爆内存了,索性就不编译了,尝试交一发,过了… 看了下 时间, 480ms,题目范围是2000, tnnd…
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2e5+177;
int main(){
int t;
cin>>t;
while(t--){
int n;
vector<int >ve[217];
int cnt[217][maxn];
cin>>n;
int x;
for(int i=1;i<=n;i++){
scanf("%d",&x);
ve[x].push_back(i);
for(int j=1;j<=200;j++){
cnt[j][i]=cnt[j][i-1];
}
cnt[x][i]++;
}
int ans=-1;
for(int i=1;i<=200;i++){
int maxx1=ve[i].size();
for(int j=0;j*2<ve[i].size();j++){
int l=ve[i][j];
int r=ve[i][ve[i].size()-1-j];
if(l==r){
break;
}
int maxx2=-1;
for(int k=1;k<=200;k++){
if(k==i)continue;
maxx2=max(maxx2,cnt[k][r]-cnt[k][l]);
}
// cout<<"$$ "<<maxx2<<" "<<i<<endl;
maxx1=max(maxx1,maxx2+(j+1)*2);
}
ans=max(ans,maxx1);
}
cout<<ans<<endl;
}
}