其他分享
首页 > 其他分享> > P1439 【模板】最长公共子序列

P1439 【模板】最长公共子序列

作者:互联网

题目链接

P1439 【模板】最长公共子序列

思路

第一种 $O(N^2)$

用f[i][j]表示第一个排列取到i位和第2个排列取到j位的公共子序列长度

$$f[i][j]=max(f[i-1][j],f[i][j-1],f[i-1][j-1])$$

最后一种情况需满足$a[i]==b[i]$

对于$50%$的数据,$n≤1000$,应该可以过

第二种 $O(n \cdot log(n) )$

把a重新标号$1$到$n$,把b中和a相同的元素跑一遍最长上升子序列就好了

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<string>
#include<cstring>
using namespace std;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int n;
int a[100005],lcs[100005];
signed main()
{
    cin>>n;
    for(int i=1;i<=n;++i)
    {
        int x;
        cin>>x;
        a[x]=i;//标记 
    }
    int len=0;
    lcs[0]=-999;
    for(int i=1;i<=n;++i)
    {
        int x;
        cin>>x;
        int now=a[x];
        if(now>lcs[len])
        {
            lcs[++len]=now;
        }
        else
        {
            int j=lower_bound(lcs+1,lcs+len+1,now)-lcs;
            lcs[j]=now; 
        }
    }
    cout<<len;
    return 0;
}

关于lower_bound请看这篇博客点这里

手打二分的代码:

来自liuzitong

#include<bits/stdc++.h>
//#include<windows.h>
using namespace std;
int a[100001],c[100001],s;
int main(int argc, char const *argv[])
{
    int n,xx;
    a[0] = -100000;
    cin>>n;
    for (int i = 1; i <= n; ++i)
    {
        scanf("%d",&xx);
        a[xx] = i;
    }
    int t;
    for (int i = 1; i <= n; ++i)
    {
        scanf("%d",&t);
        t = a[t];
        if (t > c[s])
        {
            c[++s] = t;
        }
        else{
            int l = 1,h = s,m;
            while(l <= h){
                m = (l + h) / 2;
                if(t > c[m]) l =m + 1;
                else h = m - 1;
            }
            c[l] = t;
        }
    }
    cout<<s<<endl;
    return 0;
    // for (int i = 2; i <= n; ++i)
    // {
    //  for (int j = 1; j < i; ++j)
    //  {
    //      if (b[i] > b[j] && c[i] < c[j] + 1)
    //      {
    //          c[i] = c[j] + 1;
    //      }
    //  }
    // }
    
}

标签:now,lcs,int,len,else,P1439,序列,include,模板
来源: https://www.cnblogs.com/pyyyyyy/p/10910493.html