LCS 的 NlogN作法
这个算法其实是因为LIS有NlogN的作法,把LCS转化为了LIS来做。
对于序列A{},B{},我们可以记录下来B中的每个元素在A中出现的位置,按顺序保存在一个新序列当中,
如果有多个位置按倒序写,没有就不用写,然后对这个新序列求一个LIS就是两个序列的LCS长度。
为什么这样可行呢,我们可以这样考虑,对于A序列,下标编号记为1---n1,B和A的最长公共子序列在A中对应的编号肯定是递增的,
所以B中的这些元素对应的A的编号也是递增的,为了重复计算当有多个编号时倒序存入,表示只能选一个,尽管有多个编号但在B中这只是一个元素。
A={3,9,7,10,3} B={5,3,7,3}
列出B对应的A中的编号(1--5)
5:无
3:1,5
7:3
3:1,5
如果按照15315来计算的话相当于B中的一个3当做了两个,但其实并不是,所以应是51351,LIS是1,3,5,也就是A中的3,7,3
https://vjudge.net/problem/UVA-10635
很脑洞的一道题,看似再考LCS实则要用LIS写才能不超时。
题意,给出两个序列A,B,长度分别是p+1和q+1,且A[1]=B[1]=1,A中的元素各不相同B也一样,长度不超过250^2,求AB的LCS。
用求LCS的方法算复杂度O(pq)肯定超时,由于元素都不相同,我们将A中的元素编号为1~p+1,在B中将A中出现过的元素改为对应的编号,没出现的编号为0(也可以删除)
然后的任务就是在B中找一个LIS,利用二分查找减小复杂度。
这其实就是一种LCS的O(NlogN)的作法。
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
map<int,int>M;
int main()
{ int n,m,p,q,i,k,j,t;
int a[],b[],g[];
//freopen("in.txt","r",stdin);
cin>>t;
for(int test=;test<=t;++test)
{
M.clear();
int x=;
cin>>n>>p>>q;
for(i=;i<=p+;++i)
{
scanf("%d",a+i);
if(!M[a[i]]) M[a[i]]=x++;
}
for(i=;i<=q+;++i)
{
scanf("%d",b+i);
b[i]=M[b[i]];
}
memset(g,inf,sizeof(g));
for(i=;i<=q+;++i)
{
*lower_bound(g,g+,b[i])=b[i];
}
printf("Case %d: %d\n",test,(int)(lower_bound(g,g+,inf)-g));
}
return ;
}
再来看一道,
http://www.ifrog.cc/acm/problem/1097
回忆起B在A中只有一个对应的点时,当时一直按得LIS来做但仔细想一想要求的不就是A和B的LCS吗,原来我早就写过nlogn的LCS做法竟然没有意识到。
这个问题相当于B中每个元素对应A中的多个元素,所以将匹配的A的编号记录下来做一次LIS就是答案,处理时依然要倒序插入。
倒序的好处在于如果选那么肯定只出现一个要么就不出现,不会产生一个B对应了多个A。
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
map<int,int>M;
int x[];
int g[];
int main()
{ int n,m,p,q,i,k,j,t;
while(cin>>n){int a[];p=;
for(i=;i<=n;++i)
{
for(j=;j<=;++j)
{
scanf("%d",a+j);
}sort(a+,a++,greater<int>());
for(int di=;di<=;++di)
{
if(a[di]==a[di-]) continue;
x[p++]=a[di];
}
}
memset(g,inf,sizeof(g));
for(i=;i<p;++i)
*lower_bound(g,g+p+,x[i])=x[i];
cout<<(lower_bound(g,g+p+,inf)-g)<<endl;
}
return ;
}
LCS 的 NlogN作法的更多相关文章
- LIS与LCS的nlogn解法
LIS(nlogn) #include<iostream> #include<cstdio> using namespace std; ; int a[maxn]; int n ...
- O(nlogn)实现LCS与LIS
序: LIS与LCS分别是求一个序列的最长不下降序列序列与两个序列的最长公共子序列. 朴素法都可以以O(n^2)实现. LCS借助LIS实现O(nlogn)的复杂度,而LIS则是通过二分搜索将复杂度从 ...
- uva 10635 LCS转LIS
这道题两个数组都没有重复的数字,用lcs的nlogn再适合不过了 #include <iostream> #include <string> #include <cstr ...
- 【CZY选讲·扩展LCS】
题目描述 给出两个仅有小写字母组成的字符串str1 和str2,试求出两个串的最长公共子序列. 数据范围 |str1| ⩽ 1000; |str2| ⩽ 10^6 题解: ①直接进行LCS( ...
- NYIST 760 See LCS again
See LCS again时间限制:1000 ms | 内存限制:65535 KB难度:3 描述There are A, B two sequences, the number of elements ...
- OI总结
当下考的钟声叮当响起,该走了,一年半的OI竞赛就此结束 留下了很多遗憾.也拥有过一段美好的竞赛生活 结识了一群优秀的OI战友,一起进步一起开心一起忧愁,但这一切的一切都将在今晚变成过去式,CSp的好与 ...
- dp--最长上升子序列LIS
1759:最长上升子序列 总时间限制: 2000ms 内存限制: 65536kB 描述 一个数的序列bi,当b1 < b2 < ... < bS的时候,我们称这个序列是上升的.对 ...
- 动态规划 Dynamic Programming 学习笔记
文章以 CC-BY-SA 方式共享,此说明高于本站内其他说明. 本文尚未完工,但内容足够丰富,故提前发布. 内容包含大量 \(\LaTeX\) 公式,渲染可能需要一些时间,请耐心等待渲染(约 5s). ...
- O(nlogn)LIS及LCS算法
morestep学长出题,考验我们,第二题裸题但是数据范围令人无奈,考试失利之后,刻意去学习了下优化的算法 一.O(nlogn)的LIS(最长上升子序列) 设当前已经求出的最长上升子序列长度为len. ...
随机推荐
- screenX clientX pageX区别
screenX:鼠标位置相对于用户屏幕水平偏移量,而screenY也就是垂直方向的,此时的参照点也就是原点是屏幕的左上角. clientX:跟screenX相比就是将参照点改成了浏览器内容区域的左上角 ...
- Python生成器是什么
生成器是 Python 初级开发者最难理解的概念之一,虽被认为是 Python 编程中的高级技能,但在各种项目中可以随处见到生成器的身影,你得去理解它.使用它.甚至爱上它. 提到生成器,总不可避免地要 ...
- django--个人主页建立练习
1.前端页面采用模板继承与动态模板 {% extends 'base.html' %} {% block content %} {% for article in article_list %} &l ...
- python创建进程的两种方式
1.方式1 import time import multiprocessing def task(arg): time.sleep(2) print(arg) def run(): # 进程1 p1 ...
- Java保留字和关键字
Java的关键字:java的关键字对Java的编译器有着特殊的意义,它们表示一种数据类型或者程序的结构相关. Java的保留字:为Java预留的关键字,现在还没用到,但在新Java的版本升级中可能会用 ...
- 收藏:几种开源许可证的区别!——By 阮一峰制作
乌克兰程序员Paul Bagwell,画了一张分析图,下面是阮一峰制作的中文版,非常棒,绝对的好东西,收藏这张图供日后查看:
- mongo distinct 指定条件
db.Article.distinct("字段名称",{"Comment.Reply.email" : "xxx"})
- 第二课 GCC入门之静态库以及共享库
序言: 前面一课讲了gcc的简单入门,包括gcc编译步骤:预处理:编译:汇编:链接.今天这节课就来讲下linux的库也欢迎大家吐糟共同学习. 原理: linux系统中分为2种库:静态库和共享库.静态库 ...
- OpenCL 学习step by step (5) 使用二维NDRange workgroup
http://www.cnblogs.com/mikewolf2002/archive/2012/09/07/2675634.html 在本教程中,我们使用二维NDRange来设置workgroup, ...
- 双camera景深计算 (1)
http://www.52rd.com/S_TXT/2016_6/TXT85047.HTM?WebShieldDRSessionVerify=Wz3h6srvu76qRI4MFxK8 前面介绍了双ca ...