E1. Three Blocks Palindrome (easy version)
題意:給一個數組,找最長子序列,這個子序列滿足迴文。左右中三個部分,每個部分只由一種數字構成。左、右部分一樣,左右部分數目可以同時爲0。
思路:
這大概就是cf div3最喜歡的前綴和prefix題吧,我遇到第二次了(掩面)而且上次補題的時候依然不會做 。
大致思路就是,brute force遍歷所有區間,找出同樣區間中最長的可能的同一字母串。同時找兩邊的最長的等量的同一字母串。然後更新answer。
cnt儲存每個字母的前綴和。
代碼:
題解的代碼寫得太好了(基本抄襲),給自己留個紀念吧,下次遇到前綴和存狀態字符串真的別再給我不會了QAQ
#include<bits/stdc++.h>
using namespace std;
#define f(i,n) for(int i=1;i<=int(n);++i)
#define fore(i,l,r) for(int i=int(l);i<=int(r);++i)
#define V vector<int>
#define VV vector<V>
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,tmp;
scanf("%d",&n);
V a(n+1);
//for(auto &it:a)cin>>it;
f(i,n)cin>>a[i];
VV cnt(27,V(n+1));
f(i,n){
f(j,26)cnt[j][i]=cnt[j][i-1];
++cnt[a[i]][i];
}
int ans=0;
f(i,26) ans=max(cnt[i][n],ans);
f(l,n-1) fore(r,l+1,n){
int cntin=0,cntout=0;
f(i,26){
cntin=max(cntin,cnt[i][r]-cnt[i][l-1]);
cntout=max(cntout,min(cnt[i][n]-cnt[i][r],cnt[i][l-1]));
}
ans=max(ans,cntin+cntout*2);
}
printf("%d\n",ans);
}
}