题意
给出两个长度为5*n的序列,每个序列中[1,n]每个元素恰好出现5次。问其最长公共子序列。
n<=20000
分析
枚举第一个序列,设f[i]表示到当前时刻,第二个序列中最后一位为第i位的最长公共子序列的长度是多少。然后用树状数组来加速转移即可。
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100005;
int n,pos[N/5][6],c[N],tot[N/5];
void ins(int x,int y)
{
while (x<=n) c[x]=max(c[x],y),x+=x&(-x);
}
int query(int x)
{
int ans=0;
while (x) ans=max(ans,c[x]),x-=x&(-x);
return ans;
}
int main()
{
scanf("%d",&n);n*=5;
for (int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
tot[x]++;pos[x][tot[x]]=i;
}
for (int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
for (int j=5;j>=1;j--) ins(pos[x][j],query(pos[x][j]-1)+1);
}
printf("%d",query(n));
return 0;
}