zoukankan      html  css  js  c++  java
  • 洛谷 p1439 最长公共子序列

    题目描述

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

    输入输出格式

    输入格式:

    第一行是一个数n,

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

    输出格式:

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

    输入输出样例

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

    n^2做法
    我们定义一个数组dp[i][j],表示第一个序列的前i项,第二个序列前j项中最长公共子序列
    那么可以轻易地得出dp方程:
    如果当前a[i]=b[j],dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
    否则 dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
    但是这个做法很明显只能过50%的点,其他的都会Tle;

    nlogn做法
    仔细一点,观察题目,可以知道,两个序列中数字是一样的,只不过是顺序变化了
    所以我们可以先将a序列中每个位置存起来 打个比方
    n=8 a: 8 7 6 5 4 3 2 1
    b: 8 6 4 3 1 2 5 7
    那么,1到8这些数字在a序列中位置分别为:8,7,6,5,4,3,2,1
    那么b序列中每个数在a中的位置是:1,3,5,6,8,7,4,2 设这个数组为wz[]
    很显然, 如果在wz数组中间呈上升趋势即为一段公共子序列
    那么就可以转换成为求最长不下降子序列
    所以就把这道题转换成为一个较为初级的题目
    AC代码
    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=100002;
    int number,a[N],b[N],wz[N],f[N],len=0;
    
    int read(){
        int s=0,w=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar();
        return s*w;
    }
    
    int main(){
        number=read();
        for(int i=1;i<=number;i++)a[i]=read(),wz[a[i]]=i;
        for(int i=1;i<=number;i++)b[i]=read(),b[i]=wz[b[i]],f[i]=1e9;
        f[0]=0;        
        for(int i=1;i<=number;i++){
            int l=0,r=len;
            if(b[i]>f[len])f[++len]=b[i];
            else{
                while(l<r){
                    int mid=(l+r)>>1;
                    if(f[mid]>b[i])r=mid;
                    else l=mid+1;
                }
                f[l]=min(f[l],b[i]);
            }
        }
        cout<<len;
        return 0;
    }
    
    
    
     
  • 相关阅读:
    python自学第13天 hashlib,re模块
    python自学第12天 模块
    python自学第12天 模块定义,导入,内置模块
    python自学第11天-单线程并发、迭代器,序列化,获取路径
    python自学第10天,生成器
    python自学第9天,装饰器
    python自学第8天,变量,递归
    python自学第7天,函数,参数
    彻底搞懂Session与Cookie的异同!
    你真的搞懂了Java中的<<、>>、>>>运算符嘛?
  • 原文地址:https://www.cnblogs.com/GMSD/p/11229077.html
Copyright © 2011-2022 走看看