最长公共子序列-LCS问题 (LCS与LIS在特殊条件下的转换) [洛谷1439]
题目描述
给出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]的更多相关文章
- 算法练习——最长公共子序列的问题(LCS)
问题描述: 对于两个序列X和Y的公共子序列中,长度最长的那个,定义为X和Y的最长公共子序列.X Y 各自字符串有顺序,但是不一定需要相邻. 最长公共子串(Longest Common Subst ...
- 最长公共子序列问题(LCS)——Python实现
# 最长公共子序列问题 # 作用:求两个序列的最长公共子序列 # 输入:两个字符串数组:A和B # 输出:最长公共子序列的长度和序列 def LCS(A,B): print('输入字符串数组A', ...
- 最长公共子序列问题(LCS) 洛谷 P1439
题目:P1439 [模板]最长公共子序列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 关于LCS问题,可以通过离散化转换为LIS问题,于是就可以使用STL二分的方法O(nlogn ...
- P2516 [HAOI2010]最长公共子序列 题解(LCS)
题目链接 最长公共子序列 解题思路 第一思路: 1.用\(length[i][j]\)表示\(a\)串的前\(i\)个字符与\(b\)串的前\(j\)个字符重叠的最长子串长度 2.用\(num[i][ ...
- LCS(Longest Common Subsequence 最长公共子序列)
最长公共子序列 英文缩写为LCS(Longest Common Subsequence).其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已 ...
- 算法导论-动态规划(最长公共子序列问题LCS)-C++实现
首先定义一个给定序列的子序列,就是将给定序列中零个或多个元素去掉之后得到的结果,其形式化定义如下:给定一个序列X = <x1,x2 ,..., xm>,另一个序列Z =<z1,z2 ...
- 动态规划——最长公共子序列LCS及模板
摘自 https://www.cnblogs.com/hapjin/p/5572483.html 这位大佬写的对理解DP也很有帮助,我就直接摘抄过来了,代码部分来自我做过的题 一,问题描述 给定两个字 ...
- 程序员的算法课(6)-最长公共子序列(LCS)
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_37609579/article/de ...
- [algorithm]求最长公共子序列问题
最直白方法:时间复杂度是O(n3), 空间复杂度是常数 reference:http://blog.csdn.net/monkeyandy/article/details/7957263 /** ** ...
随机推荐
- JAVA追加写入文本文件
public void method1() { FileWriter fw = null; try { //如果文件存在,则追加内容:如果文件不存在,则创建文件 File f=new File(&qu ...
- java 解析域名得到host
// 形如https://www.baidu.com 或 www.baidu.com, 判断这两种情况,并解析前者去掉http头,传入domain host // 方案1:正则表达式 + URI解析方 ...
- TodoMVC:帮助你选择一个MV*框架
开发者现在有很多的MV*框架选择来组织开发web应用程序.Backbone. Ember.AngularJS.Spine… 新的稳定解决方案列表持续增长,但你如何决定在海量的框架中选择哪个使用? 为了 ...
- Debug.Assert vs Exception Throwing(转载)
来源 Q: I've read plenty of articles (and a couple of other similar questions that were posted on Stac ...
- mycat配置文件备份
schema.xml <?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd&q ...
- context日志
class Program { static void Main(string[] args) { List<wolf_example> Listw; using (var ctx = n ...
- [转] UniCode编码表
Unicode编码则是采用双字节16位来进行编号,可编65536字符,基本上包含了世界上所有的语言字符,它也就成为了全世界一种通用的编码,而且用十六进制4位表示一个编码,非常简结直观,为大多数开发者所 ...
- [转] JavaScript设计模式之发布-订阅模式(观察者模式)-Part1
<JavaScript设计模式与开发实践>读书笔记. 发布-订阅模式又叫观察者模式,它定义了对象之间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖它的对象都将得到通知. 例如 ...
- 2018软工实践作业八之UML设计
1. 团队信息 队名:小白吃队 成员: 后敬甲 031602409 卢泽明 031602328 蔡文斌 031602301 葛亮 031602617 刘浩 031602423 黄泽 031602317 ...
- url、querystring模块获取请求request.url中的不同部分图解
url.parse(string).query | url.parse(string).pathname | | | | | ------ ------------------- http://loc ...