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

求a[] 与b[]中的LCS

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

for(int i=1;i<=n;i++){
local[b[i]]=i;
}
for(int i=1;i<=n;i++){
lis[i]=local[a[i]];
}

当序列中有元素重复时,我们们需要保证对于每个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

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int read(){
int rv=0,fh=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') fh=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
rv=(rv<<1)+(rv<<3)+c-'0';
c=getchar();
}
return fh*rv;
}
int n,a[100005],b[100005],local[100005],lis[100005],dp[100005];
int main(){
freopen("in.txt","r",stdin);
n=read();
for(int i=1;i<=n;i++){
a[i]=read();
}
for(int i=1;i<=n;i++){
b[i]=read();
}
for(int i=1;i<=n;i++){
local[b[i]]=i;
}
for(int i=1;i<=n;i++){
lis[i]=local[a[i]];
}
dp[1]=lis[1];dp[0]++;
for(int i=2;i<=n;i++){
int l=1,r=dp[0],m=0;
while(l<=r){
m=(l+r)>>1;
if(dp[m]<=lis[i]){
l=m+1;
}else r=m-1;
}
if(l==1){
dp[l]=min(dp[l],lis[i]);
}else {
if(l==dp[0]+1){
dp[0]++;
dp[l]=lis[i];
}else {
dp[l]=min(dp[l],lis[i]);
}
}
}
cout<<dp[0];
fclose(stdin);
return 0;
}

洛谷 [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. BZOJ3529: [Sdoi2014]数表

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3529 挺恶心的数论TAT... 设f[i]是i的约数和,这个可以nln(n)扫出来. ans= ...

  2. 安装JDK出现错误:-bash: /usr/java/jdk1.7.0_71/bin/java: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory解决办法

    1.错误描述:安装好jdk之后,通过java -version,javac,java等命令测试是否安装成功时出现错误-bash: /usr/java/jdk1.7.0_71/bin/java: /li ...

  3. nodejs学习笔记 —— 异步编程解决方案

    在js或者node编程中,由于异步的频繁和广度使用,使得回调和嵌套的深度导致编程的体验遇到一些挑战,如果写出优雅和好看的代码,本文主要针对异步编程的主流方案做一些总结 1.事件发布/订阅模式 事件监听 ...

  4. java通过smtp发送电子邮件

    package com.sm.modules.oa.web; import javax.mail.Session; import javax.mail.Transport; import javax. ...

  5. Oracle_复杂查询综合

    Oracle_复杂查询综合 -- 1.列出所有员工的年工资,按年薪从低到高排序. select,) income from emp order by income;   -- 2.列出薪金比" ...

  6. 关于将dede织梦data目录迁移出web目录

    关于将dede织梦data目录迁移出web目录织梦官方提供了一个教程,但是如果你是按照他们提供的教程做的话会出现很多问题.比如验证码问题,图片显示问题等等一大堆.织梦官方这种是很不负责任的,因为那个教 ...

  7. 微信小程序左右滑动切换图片酷炫效果(附效果)

    开门见山,先上效果吧!感觉可以的用的上的再往下看. 心动吗?那就继续往下看! 先上页面结构吧,也就是wxml文件,其实可以理解成微信自己封装过的html,这个不多说了,不懂也没必要往下看了. < ...

  8. C#、Java之比较

    很多人说C#是微软用来和Java抗衡的武器,因为二者在很大程度上有着惊人的相似,尽管如此,两者不同的地方也很多,所谓"于细微处见差异".那么两者的相似和区别都在什么地方呢?我们从今 ...

  9. java ecplise配置

    运行java项目首先配置java运行时环境:Window->Preferences->Java->Installed JREs 修改为jdk:C:\Program Files\Jav ...

  10. 【转】判断点在多边形内(matlab)

    inpolygon -Points inside polygonal region Syntax IN = inpolygon(X,Y,xv,yv)[IN ON] = inpolygon(X,Y,xv ...