[ACM] 【prefix/子序列】Codeforces Round #634 (Div.3) Three Blocks Palindrome (easy version)

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);
	}
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章