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

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;
}
posted @ 2024-07-27 09:41  wscqwq  阅读(3)  评论(0编辑  收藏  举报