51nod-基因匹配+luogu-【模板】最長公共子序列

wscqwq發表於2024-07-27

https://www.luogu.com.cn/problem/P1439

https://class.51nod.com/Html/Textbook/ChapterIndex.html#textbookId=126&chapterId=338

以上兩個都是特例,一個是每個元素不重複,一個是每個元素均有5個。

image-20240727093531395

正確性說明參考:https://www.luogu.com.cn/article/1bcs9052

由於一般情況可能出現多個,就需要類似於上面的處理,倒序是防止一組內選取多個,多個編號是因為只要滿足下標中任意一個均可。

最佳化可以考慮二分或者樹狀陣列(因為離散化過,比較方便了)。

複雜度 \(O(25n\log25n)\)

#include<iostream>
#include<algorithm>
using namespace std;
const int N=100010;
int a[5*N],n5,s1[N],s2[N],n,t[N][6],f[5*N],c[5*N];
void add(int x,int v){
	for(;x<=n5;x+=x&-x)c[x]=max(c[x],v);
}
int sum(int x){
	int res=0;
	for(;x;x-=x&-x)res=max(res,c[x]);
	return res;
}
int main(){
	#ifdef LOCAL
	freopen("1.txt","r",stdin);
	#endif
	#ifndef LOCAL
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	#endif
	cin>>n;
	n*=5;
	for(int i=1;i<=n;++i)cin>>s1[i],t[s1[i]][++t[s1[i]][0]]=i;
	for(int i=1;i<=n;++i){
		cin>>s2[i];
		for(int j=5;j;--j)
			a[++n5]=t[s2[i]][j];
	}
	int ans;
	for(int i=1;i<=n5;++i){
		f[i]=sum(a[i]-1)+1;
		add(a[i],f[i]);
		ans=max(ans,f[i]);
	}
	cout<<ans;
	return 0;
}

相關文章