题目描述

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

输入

第一行是一个数n,

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

输出

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

输入样例

5
3 2 1 4 5
1 2 3 4 5
输出样例

3

说明

对于50%的数据,n≤1000

对于100%的数据,n≤100000

思路

常见的LCS问题是通过O(n2)的DP解决的,显然此题的数据是过不去的

如何想办法?

这里就要参考在特殊条件下LCS与LIS(最长上升序列)的转换

我们记录下第一个排列每一个数字出现的位置,即Hash[ ai ] = i

而这个序列再按第二个排列排序,即新型成的序列Seq[ i ] = Hash[ bi ]

这样做了以后发现有什么规律呢?

新的序列Seq是满足B排列的先后顺序单调递增的,而在Seq的Hash值是按A排列的先后顺序单调递增的

那么在Seq中找到的最长上升序列就是同时满足A序列和B序列的先后关系的一个子序列

这样就把LCS成功的转换成了LIS问题

我们知道LIS的问题是可以O(n log n) 的解决的,在此不作赘述。

那么我们前面提到的特殊条件是什么呢?

由于这里记录的是Hash值,所以不能有重复的数字。

代码

 #include<set>
#include<map>
#include<stack>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define RG register int
#define rep(i,a,b) for(RG i=a;i<=b;i++)
#define per(i,a,b) for(RG i=a;i>=b;i--)
#define ll long long
#define inf (1<<30)
#define maxn 100005
using namespace std;
int n,cnt;
int hash[maxn],seq[maxn],dp[maxn];
inline int read()
{
int x=,f=;char c=getchar();
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} void solve()
{
int l,r,mx=,mid,p;
rep(i,,n)
{
l=,r=mx,p=;
while(l<=r)
{
mid=(l+r)>>;
if(dp[mid]<=seq[i]) p=mid,l=mid+;
else r=mid-;
}
if(p==mx) dp[++mx]=seq[i];
else dp[p+]=min(dp[p+],seq[i]);
}
cout<<mx;
} int main()
{
int tmp;
n=read();
rep(i,,n) tmp=read(),hash[tmp]=i;
rep(i,,n) tmp=read(),seq[++cnt]=hash[tmp];//如果两个序列的值有不相同的,请在逗号处加上 if(hash[tmp]),此题因为是排列所以不用加
solve();
return ;
}

最长公共子序列-LCS问题 (LCS与LIS在特殊条件下的转换) [洛谷1439]的更多相关文章

  1. 算法练习——最长公共子序列的问题(LCS)

    问题描述: 对于两个序列X和Y的公共子序列中,长度最长的那个,定义为X和Y的最长公共子序列.X  Y   各自字符串有顺序,但是不一定需要相邻. 最长公共子串(Longest Common Subst ...

  2. 最长公共子序列问题(LCS)——Python实现

      # 最长公共子序列问题 # 作用:求两个序列的最长公共子序列 # 输入:两个字符串数组:A和B # 输出:最长公共子序列的长度和序列 def LCS(A,B): print('输入字符串数组A', ...

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

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

  4. P2516 [HAOI2010]最长公共子序列 题解(LCS)

    题目链接 最长公共子序列 解题思路 第一思路: 1.用\(length[i][j]\)表示\(a\)串的前\(i\)个字符与\(b\)串的前\(j\)个字符重叠的最长子串长度 2.用\(num[i][ ...

  5. LCS(Longest Common Subsequence 最长公共子序列)

    最长公共子序列 英文缩写为LCS(Longest Common Subsequence).其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已 ...

  6. 算法导论-动态规划(最长公共子序列问题LCS)-C++实现

    首先定义一个给定序列的子序列,就是将给定序列中零个或多个元素去掉之后得到的结果,其形式化定义如下:给定一个序列X = <x1,x2 ,..., xm>,另一个序列Z =<z1,z2  ...

  7. 动态规划——最长公共子序列LCS及模板

    摘自 https://www.cnblogs.com/hapjin/p/5572483.html 这位大佬写的对理解DP也很有帮助,我就直接摘抄过来了,代码部分来自我做过的题 一,问题描述 给定两个字 ...

  8. 程序员的算法课(6)-最长公共子序列(LCS)

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_37609579/article/de ...

  9. [algorithm]求最长公共子序列问题

    最直白方法:时间复杂度是O(n3), 空间复杂度是常数 reference:http://blog.csdn.net/monkeyandy/article/details/7957263 /** ** ...

随机推荐

  1. C#学习-构造函数

    如果没有为类显式地定义一个构造函数,则C#编译器会自动生成一个函数体为空的默认无参的实例构造函数. 构造函数主要用于创建类的实例对象. 当调用构造函数创建一个对象时,构造函数会为对象分配内存空间,并初 ...

  2. .net remoting(1)简单例子

    1.例子(程序间的通讯) class Program { static void Main(string[] args) { HttpChannel _channel = ); ChannelServ ...

  3. 关于64位 MS SQL 导入导出 Oracle 引发 ORA-06413 的解决方法

    如果在X64系统下我们想利用 MS SQL 的DTS导入导出 Oracle 数据,由 oracle 不支持路径中包含")",会引发 ORA-06413:连接未打开错误 解决的办法很 ...

  4. bzoj2683&&bzoj4066

    题解: 前一题不是强制在线,后一题是强制在线 树套树空间会炸 说一下cdq分治+树状数组 首先我们利用cdq分治使得查询和操作保证先后关系 然后矩阵查询变成4个矩阵的差 那么我们就可以运用扫描线的方法 ...

  5. UIActionSheet的常用方法

    enum UIActionSheetStyle : Int { case Automatic // take appearance from toolbar style otherwise uses ...

  6. MySQL常用引擎的锁机制

    一.引言                                                                                                 ...

  7. day3.python字符串格式化

    字符串格式化 注意:若在格式化输出中还需要再加%,需要两个%来代替 方法1:%控制格式化输出 例1: print("I'm %s. I'm %d year old" % ('Vam ...

  8. error: Microsoft Visual C++ 14.0 is required.

    缺少包的依赖!! 解决办法1. 安装 Microsoft visual c++ 14.0 https://964279924.ctfile.com/fs/1445568-239446865 或 htt ...

  9. Python学习(二十九)—— pymysql操作数据库优化

    转载自:http://www.cnblogs.com/liwenzhou/articles/8283687.html 我们之前使用pymysql操作数据库的操作都是写死在视图函数中的,并且很多都是重复 ...

  10. JavaSE| 面向对象的三大特征

    1.面向对象的基本特征之一:封装Encapsulation 目的:隐藏实现细节,让使用者方便,让代码更安全 将对象的属性和行为封装起来,其载体就是类.类通常对客户隐藏其实现细节,这就是封装的思想. 封 ...