zoukankan      html  css  js  c++  java
  • P1439 排列LCS问题

    P1439 排列LCS问题

      • 56通过
      • 220提交
    • 题目提供者yeszy
    • 标签二分动态规划
    • 难度普及+/提高

    提交该题 讨论 题解 记录

    最新讨论

    • 暂时没有讨论

    题目描述

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

    输入输出格式

    输入格式:

    第一行是一个数n,

    接下来两行,每行为n个数,为自然数1-n的一个排列。

    输出格式:

    一个数,即最长公共子序列的长度

    输入输出样例

    输入样例#1:
    5 
    3 2 1 4 5
    1 2 3 4 5
    
    输出样例#1:
    3

    说明

    【数据规模】

    对于50%的数据,n≤1000

    对于100%的数据,n≤100000

    题解:

    看到10W的规模,大致可以断定此题应该用O(nlogn)的解法,朴素的LCS算法时间复杂度为O(n^2),明显不可行。

    首先简化一下问题,假设P1恰好为单调递增的1,2,3,...n,那么很显然答案就是P2的最长上升子序列的长度(想一想,为什么?)

    问题是P1并非单调递增的,但我们可以假定它就是1,2,3,...,n,将P1[1]映射到1,P1[2]映射到2,……然后再将P2作相同的变换即可,这样只要求P2的最长上升子序列了。

    最长上升子序列是有O(nlogn)算法的,大致过程如下:

    建立栈a,每读入一个元素x,若x比栈顶元素大则x进栈,否则在栈中二分找到第一个大于x的元素a[k],并用x替换它,做完以后栈的大小就是序列的最长上升子序列的长度。

    AC代码:

    (头文件自动忽略就好)

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<ctime>
    #include<cmath>
    #include<string>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<map>
    using namespace std;
    #define ll long long
    #define N 100010
    #define inf 1100000000
    #define linf 999999999999999LL
    #define xx first
    #define yy second
    typedef pair<int,int> diy;
    inline const int read(){
        register int x=0,f=1;
        register char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int n,m,len;
    int a[N],b[N];
    int main(){
        n=read();
        for(int i=1;i<=n;i++) a[read()]=i;
        for(int i=1;i<=n;i++) b[i]=a[read()];
        memset(a,0,sizeof a);
        a[len=1]=b[1];
        for(int i=2;i<=n;i++){
            if(b[i]>a[len])
                a[++len]=b[i];
            else
                a[lower_bound(a+1,a+len+1,b[i])-a]=b[i];
        }
        printf("%d
    ",len);
        return 0;
    }
  • 相关阅读:
    pat 甲级 1065. A+B and C (64bit) (20)
    pat 甲级 1064. Complete Binary Search Tree (30)
    pat 甲级 1010. Radix (25)
    pat 甲级 1009. Product of Polynomials (25)
    pat 甲级 1056. Mice and Rice (25)
    pat 甲级 1078. Hashing (25)
    pat 甲级 1080. Graduate Admission (30)
    pat 甲级 团体天梯 L3-004. 肿瘤诊断
    pat 甲级 1099. Build A Binary Search Tree (30)
    Codeforce 672B. Different is Good
  • 原文地址:https://www.cnblogs.com/shenben/p/5794704.html
Copyright © 2011-2022 走看看