zoukankan      html  css  js  c++  java
  • P3402 最长公共子序列(nlogn)

    P3402 最长公共子序列

    题目背景

    DJL为了避免成为一只咸鱼,来找Johann学习怎么求最长公共子序列。

    题目描述

    经过长时间的摸索和练习,DJL终于学会了怎么求LCS。Johann感觉DJL孺子可教,就给他布置了一个课后作业:

    给定两个长度分别为n和m的序列,序列中的每个元素都是正整数。保证每个序列中的各个元素互不相同。求这两个序列的最长公共子序列的长度。

    DJL最讨厌重复劳动,所以不想做那些做过的题。于是他找你来帮他做作业。

    输入输出格式

    输入格式:

    第一行两个整数n和m,表示两个数列的长度。

    第二行一行n个整数a_1,a_2,…,a_n,保证1≤a_i≤〖10〗^9。

    第三行一行m个整数b_1,b_2,…,b_m,保证1≤b_i≤〖10〗^9。

    输出格式:

    一行一个整数,表示两个数列的最长公共子序列的长度。

    输入输出样例

    输入样例#1:
    6 6
    1 3 5 7 9 8
    3 4 5 6 7 8
    
    输出样例#1:
    4

    说明

    对于40%的数据,n, m≤3000

    对于100%的数据,n, m≤300000

    分析

    对于n方的算法,这道题显然过不去,并且这道题每个数字只出现一次,可以用一个“nlogn”的算法,(加引号的)这个算法只适用于A和B中每个数出现的次数是一个很小的数,这一点题目刚好满足。

    具体呢,就是对于在B序列中的元素x,我们在A中找到x的出现位置(在A中的位置)并按降序写下来。然后B中的所有x都有对应的数字,这些数字就是序列C,对C求最长不下降子序列。得到的答案即为A和B的LCS长度。

    举个栗子:A={c,a,b,e,d,a,b},B={a,d,c,a,d,b},C={6,2, 5, 1, 6,2, 5, 7,3}

    比如B中的a他在A中出现的位置是2,6,按降序后就是6,2;其他的同理。

    因为求最长不下降子序列有(nlogn)的算法(http://www.cnblogs.com/mjtcn/p/7197034.html),所以,这也就是nlogn的算法了,再加上预处理出,

    这个题这样差不多就完成了,但是,为了方便用map写的,洛谷上只过了7个点,改读入优化,加上inline就过了,可以用哈希写,比map快多了

    code

     1 #include<cstdio>
     2 #include<map>
     3 #include<algorithm>
     4 
     5 using namespace std;
     6 const int MAXN = 300100;
     7 int f[MAXN];
     8 
     9 map<int,int>p;
    10 inline int read()
    11 {
    12     int x = 0;char ch = getchar();
    13     while (ch<'0'||ch>'9') ch = getchar();
    14     while (ch>='0'&&ch<='9') x = x*10+ch-'0',ch = getchar() ;
    15     return x;
    16 }
    17 inline int search(int l,int r,int x)
    18 {
    19     while (l<r)
    20     {
    21         int mid = (l+r)>>1;
    22         if (x<=f[mid]) r = mid;
    23         else l = mid+1;
    24     }
    25     return l;
    26 }
    27 int main()
    28 {
    29     int n = read(),m = read(),len = 0;
    30     for (int x,i=1; i<=n; ++i) 
    31         x = read(),p[x] = i;
    32     for (int a,x,i=1; i<=m; ++i) 
    33     {
    34         a = read();
    35         x = p[a];
    36         if (!x) continue;
    37         if (x>f[len]) f[++len] = x;
    38         else 
    39         {
    40             int p = search(1,len,x);
    41             f[p] = x;
    42         }
    43     }
    44     printf("%d",len);    
    45     return 0;
    46 }
  • 相关阅读:
    测试方案
    如何编写一个好的测试计划
    一个好的测试过程
    java后台生成echarts图表并保存图片
    Javascript数组排序,并获取排序后位置对应的原索引(堆排序实现)
    修改tomcat编码方式
    json序列化反序列化后function丢失
    Mysql数据库存取性能优化
    java创建文件
    Java POI导出ppt简单实现
  • 原文地址:https://www.cnblogs.com/mjtcn/p/7354523.html
Copyright © 2011-2022 走看看