可以发现只有当两个序列中都没有重复元素时(1~n的排列)此种优化才是高效的,不然可能很不稳定。

求a[] 与b[]中的LCS

通过记录lis[i]表示a[i]在b[]中的位置,将LCS问题转化为最长上升子序列问题,转化方法如下:

  1. for(int i=1;i<=n;i++){
  2. local[b[i]]=i;
  3. }
  4. for(int i=1;i<=n;i++){
  5. lis[i]=local[a[i]];
  6. }

当序列中有元素重复时,我们们需要保证对于每个a[i]所记录的位置必须是逆序的,以保证一个元素只取一次。

例:举例说明:

A:abdba

B:dbaaba

则1:先顺序扫描A串,取其在B串的所有位置:

2:a(2,3,5) b(1,4) d(0)。

3:用每个字母的反序列替换,则最终的最长严格递增子序列的长度即为解。

替换结果:532 41 0 41 532

代码如下:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <cmath>
  6. using namespace std;
  7. int read(){
  8. int rv=0,fh=1;
  9. char c=getchar();
  10. while(c<'0'||c>'9'){
  11. if(c=='-') fh=-1;
  12. c=getchar();
  13. }
  14. while(c>='0'&&c<='9'){
  15. rv=(rv<<1)+(rv<<3)+c-'0';
  16. c=getchar();
  17. }
  18. return fh*rv;
  19. }
  20. int n,a[100005],b[100005],local[100005],lis[100005],dp[100005];
  21. int main(){
  22. freopen("in.txt","r",stdin);
  23. n=read();
  24. for(int i=1;i<=n;i++){
  25. a[i]=read();
  26. }
  27. for(int i=1;i<=n;i++){
  28. b[i]=read();
  29. }
  30. for(int i=1;i<=n;i++){
  31. local[b[i]]=i;
  32. }
  33. for(int i=1;i<=n;i++){
  34. lis[i]=local[a[i]];
  35. }
  36. dp[1]=lis[1];dp[0]++;
  37. for(int i=2;i<=n;i++){
  38. int l=1,r=dp[0],m=0;
  39. while(l<=r){
  40. m=(l+r)>>1;
  41. if(dp[m]<=lis[i]){
  42. l=m+1;
  43. }else r=m-1;
  44. }
  45. if(l==1){
  46. dp[l]=min(dp[l],lis[i]);
  47. }else {
  48. if(l==dp[0]+1){
  49. dp[0]++;
  50. dp[l]=lis[i];
  51. }else {
  52. dp[l]=min(dp[l],lis[i]);
  53. }
  54. }
  55. }
  56. cout<<dp[0];
  57. fclose(stdin);
  58. return 0;
  59. }

洛谷 [p1439] 最长公共子序列 (NlogN)的更多相关文章

  1. 洛谷P1439 最长公共子序列(LCS问题)

    题目描述 给出1-n的两个排列P1和P2,求它们的最长公共子序列. 输入输出格式 输入格式: 第一行是一个数n, 接下来两行,每行为n个数,为自然数1-n的一个排列. 输出格式: 一个数,即最长公共子 ...

  2. 洛谷P3402 最长公共子序列

    题目背景 DJL为了避免成为一只咸鱼,来找Johann学习怎么求最长公共子序列. 题目描述 经过长时间的摸索和练习,DJL终于学会了怎么求LCS.Johann感觉DJL孺子可教,就给他布置了一个课后作 ...

  3. 【算法】最长公共子序列(nlogn)

    转载注明出处:http://blog.csdn.net/wdq347/article/details/9001005 (修正了一些错误,并自己重写了代码) 最长公共子序列(LCS)最常见的算法是时间复 ...

  4. 最长公共子序列 nlogn

    先来个板子 #include<bits/stdc++.h> using namespace std; , M = 1e6+, mod = 1e9+, inf = 1e9+; typedef ...

  5. 洛谷P2766 最长递增子序列问题

    https://www.luogu.org/problemnew/show/P2766 注:题目描述有误,本题求的是最长不下降子序列 方案无限多时输出 n 网络流求方案数,长见识了 第一问: DP 同 ...

  6. 洛谷P4608 [FJOI2016]所有公共子序列问题 【序列自动机 + dp + 高精】

    题目链接 洛谷P4608 题解 建个序列自动机后 第一问暴搜 第二问dp + 高精 设\(f[i][j]\)为两个序列自动机分别走到\(i\)和\(j\)节点的方案数,答案就是\(f[0][0]\) ...

  7. P1439 最长公共子序列(nlognLCS问题)

    模板 #include <iostream> #include <cstdio> using namespace std; ],loc[],b[],k,n,l,r,mid; i ...

  8. 最长公共子序列问题(LCS) 洛谷 P1439

    题目:P1439 [模板]最长公共子序列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 关于LCS问题,可以通过离散化转换为LIS问题,于是就可以使用STL二分的方法O(nlogn ...

  9. 洛谷 P1439 【模板】最长公共子序列

    \[传送门啦\] 题目描述 给出\(1-n\)的两个排列\(P1\)和\(P2\),求它们的最长公共子序列. 输入输出格式 输入格式: 第一行是一个数\(n\), 接下来两行,每行为\(n\)个数,为 ...

随机推荐

  1. 向ajaxform和ajaxgrid中添加数据

    --ajaxform function add(){ $.request({ action:"add", success:onaddcomplete }); } function ...

  2. Dora.Interception, 一个为.NET Core度身打造的AOP框架[3]:Interceptor的注册

    在<不一样的Interceptor>中我们着重介绍了Dora.Interception中最为核心的对象Interceptor,以及定义Interceptor类型的一些约定.由于Interc ...

  3. cesium编程入门(三)开始使用cesium开发

    搭建最简的开发环境 这一节来搭建一个最简单的能运行的helloworld,以后的代码也会在这一节的基础上慢慢增加 创建文件夹 mkdir cesium-test cd cesium-test 引入编译 ...

  4. 版本控制——TortoiseSVN (1)安装与配置

    =================================版权声明================================= 版权声明:原创文章 禁止转载  请通过右侧公告中的“联系邮 ...

  5. 【编程技巧】一些 NSArray 的基本操作代码例子

    /*---------------------------切分数组------------------------------*/ //从字符串分割到数组- componentsSeparatedBy ...

  6. hive分区(partition)

    网上有篇关于hive的partition的使用讲解的比较好,转载了:一.背景1.在Hive Select查询中一般会扫描整个表内容,会消耗很多时间做没必要的工作.有时候只需要扫描表中关心的一部分数据, ...

  7. Netty 拆包粘包和服务启动流程分析

    Netty 拆包粘包和服务启动流程分析 通过本章学习,笔者希望你能掌握EventLoopGroup的工作流程,ServerBootstrap的启动流程,ChannelPipeline是如何操作管理Ch ...

  8. Java的栈和队列

    package com.ipmotor.sm.db;import java.util.LinkedList;import java.util.Queue;import java.util.Stack; ...

  9. cmd 指令

    dir  展示当前文件夹内的文件 mkdir 创建文件夹 c:  访问C盘 (d: f:) cd\ 返回主文件 cd .. 返回上一文件夹 cd test  打开文件夹 访问文件夹 rd 删除文件夹 ...

  10. linux_网站计量单位

    IP 独立IP数,是不同IP地址的计算机访问网站时被计算的总次数,独立IP数是衡量网站流量的一个重要指标,一般一天内相同IP地址的客户端访问网页只被计算为一次,记录独立IP的时间为一天或一个月,目前通 ...