题目描述:

给出1-n的两个排列P1和P2,求它们的最长公共子序列。

题解:

此题要求O(nlogn)解决LCS。

我们考虑LCS转LIS,二分维护。

我们保证一个序列是单调的,那么将另一个序列按照标号排序,会发现转换后的LIS就是原序列的LCS。

但是这种解法有一个限制——两个排列要求是1~n的。

附上代码:

#include<cstdio>
int a[100001],a1[100001],c[100001],n,b[100001],d[100001],l,cnt,len,idx,ans;
int find(int l,int r,int x)
{
    while(l<r)
    {
        int mid=(l+r)/2;
        if(d[mid]>=x)
            r=mid;
        else
            l=mid+1;
    }
    return l;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&b[i]);
        a1[b[i]]=i;
    }
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&c[i]);
        a[i]=a1[c[i]];
    }
    for(int i=1;i<=n;++i)
    {
        idx=find(1,len+1,a[i]);
        if(idx>len)
            ++len;
        d[idx]=a[i];
    }
    printf("%d",len);
}

 

相关文章:

  • 2021-08-28
  • 2021-11-07
  • 2022-12-23
  • 2021-06-25
  • 2021-11-29
  • 2021-10-15
  • 2022-12-23
  • 2022-01-05
猜你喜欢
  • 2022-03-04
  • 2022-12-23
  • 2022-02-18
  • 2021-06-21
  • 2022-12-23
  • 2021-04-22
相关资源
相似解决方案