这个算法其实是因为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作法的更多相关文章

  1. LIS与LCS的nlogn解法

    LIS(nlogn) #include<iostream> #include<cstdio> using namespace std; ; int a[maxn]; int n ...

  2. O(nlogn)实现LCS与LIS

    序: LIS与LCS分别是求一个序列的最长不下降序列序列与两个序列的最长公共子序列. 朴素法都可以以O(n^2)实现. LCS借助LIS实现O(nlogn)的复杂度,而LIS则是通过二分搜索将复杂度从 ...

  3. uva 10635 LCS转LIS

    这道题两个数组都没有重复的数字,用lcs的nlogn再适合不过了 #include <iostream> #include <string> #include <cstr ...

  4. 【CZY选讲·扩展LCS】

    题目描述 给出两个仅有小写字母组成的字符串str1 和str2,试求出两个串的最长公共子序列. 数据范围 |str1| ⩽ 1000; |str2| ⩽ 10^6 题解:    ①直接进行LCS( ...

  5. NYIST 760 See LCS again

    See LCS again时间限制:1000 ms | 内存限制:65535 KB难度:3 描述There are A, B two sequences, the number of elements ...

  6. OI总结

    当下考的钟声叮当响起,该走了,一年半的OI竞赛就此结束 留下了很多遗憾.也拥有过一段美好的竞赛生活 结识了一群优秀的OI战友,一起进步一起开心一起忧愁,但这一切的一切都将在今晚变成过去式,CSp的好与 ...

  7. dp--最长上升子序列LIS

    1759:最长上升子序列 总时间限制:  2000ms 内存限制:  65536kB 描述 一个数的序列bi,当b1 < b2 < ... < bS的时候,我们称这个序列是上升的.对 ...

  8. 动态规划 Dynamic Programming 学习笔记

    文章以 CC-BY-SA 方式共享,此说明高于本站内其他说明. 本文尚未完工,但内容足够丰富,故提前发布. 内容包含大量 \(\LaTeX\) 公式,渲染可能需要一些时间,请耐心等待渲染(约 5s). ...

  9. O(nlogn)LIS及LCS算法

    morestep学长出题,考验我们,第二题裸题但是数据范围令人无奈,考试失利之后,刻意去学习了下优化的算法 一.O(nlogn)的LIS(最长上升子序列) 设当前已经求出的最长上升子序列长度为len. ...

随机推荐

  1. 如何编译部署 UIKit 离线文档?

    如何编译部署 UIKit 离线文档? Whis is UIKit? Note:部署在 Windows 系统会出现路径错误情况,这里采用在 Debian 系统上进行编译和部署. 1. 安装一些前置工具 ...

  2. sql 锁类型与锁机制

    SQL Server锁类型(SQL)收藏1. HOLDLOCK: 在该表上保持共享锁,直到整个事务结束,而不是在语句执行完立即释放所添加的锁.   2. NOLOCK:不添加共享锁和排它锁,当这个选项 ...

  3. 手动拼写出来的sp_who结果集

    SELECT SPID = er.session_id  ,STATUS = ses.STATUS  ,[Login] = ses.login_name  ,Host = ses.host_name  ...

  4. rest_framework 响应器

    一 作用 根据 用户请求URL 或 用户可接受的类型,筛选出合适的 渲染组件.用户请求URL:    http://127.0.0.1:8000/test/?format=json    http:/ ...

  5. CWM是什么?

    CWM [1]  (CommonWarehouseMetamodel公共仓库元模型)是OMG组织在数据仓库系统中定义了一套完整的元模型体系结构,用于数据仓库构建和应用的元数据建模.公共仓库元模型指定的 ...

  6. 012-JDK可视化监控工具-jstack

    一.概述 jstack是java虚拟机自带的一种堆栈跟踪工具.jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项&qu ...

  7. kotlin-plugin-1.1.2-release-Studio2.3-1.zip 下载地址

    1 官方下载地址,下载较慢,我家100m联通光纤,下载也就120k左右 http://jetbrains-plugins.s3.amazonaws.com/6954/34562/kotlin-plug ...

  8. SQL LEFT JOIN

    SQL LEFT JOIN 关键字 SQL LEFT JOIN 关键字 LEFT JOIN 关键字会从左表 (table_name1) 那里返回所有的行,即使在右表 (table_name2) 中没有 ...

  9. Part01、memcache 缓存

    Python操作 RabbitMQ.Redis.Memcache.SQLAlchemy 目录 一. Memcached Memcached安装和基本使用 Python操作Memcached2.1 se ...

  10. 你真的会用javascript?

    偶然在csdn看到几个js的小题,考察的都是很基础的知识,拿来分享一下1. 1 2 3 4 if (!("a" in window)) { var a = 1; } alert(a ...