P12738 题解
题意
给定两个序列
题解
由于有相同限制,直接一对一对选择。注意到若
据此显然有时空
由于 DP 值也是
显然
代码
#include<iostream>
#include<algorithm>
#define lb lower_bound
using namespace std;
const int N=1.5e4+10;
int n,m,k,a[N],b[N],na[N],nb[N],pre[N<<1],c[N<<1],f[2][N],g[N<<1];
int main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i],c[++k]=a[i];
for(int i=1;i<=m;i++) cin>>b[i],c[++k]=b[i];
sort(c+1,c+1+k),k=unique(c+1,c+1+k)-c-1;
for(int i=1;i<=n;i++) a[i]=lb(c+1,c+1+k,a[i])-c;
for(int i=1;i<=m;i++) b[i]=lb(c+1,c+1+k,b[i])-c;
for(int i=n;i;i--) na[i]=pre[a[i]],pre[a[i]]=i;
for(int i=1;i<=k;i++) pre[i]=0;
for(int i=m;i;i--) nb[i]=pre[b[i]],pre[b[i]]=i;
for(int x=1;;x++)
{
int cur=(x&1),last=1-cur,j=m;
for(int i=0;i<=n;i++) f[cur][i]=N;
for(int t=1;t<=k;t++) g[t]=N;
for(int i=1;i<=n;i++)
{
while(f[last][i-1]<j&&j)
{
if(nb[j]) g[b[j]]=min(g[b[j]],nb[j]);
j--;
}
if(na[i]) f[cur][na[i]]=min(f[cur][na[i]],g[a[i]]);
f[cur][i]=min(f[cur][i],f[cur][i-1]);
}
if(f[cur][n]==N) {cout<<x*2-2; break;}
}
return 0;
}