最长公共子序列的nlogn算法——bsoj1139
来源:互联网 发布:centos iso镜像下载64 编辑:程序博客网 时间:2024/04/30 04:30
#include<iostream>#include<algorithm>#include<cstring>#include<cstdio> using namespace std; int n,i,f[100000+9],a[100000+9],b[100000+9];int x;int main(){while(cin>>n){for(int i=1;i<=n;i++){scanf("%d",&x);a[x]=i;}for(int i=1;i<=n;i++){scanf("%d",&x);b[a[x]]=i;}f[1]=b[1];int len=1;for(int i=2;i<=n;i++)if(b[i]>f[len])f[++len]=b[i];else{int l=1,r=len,mid;while(l<=r){mid=(l+r)/2;if(f[mid]<b[i])l=mid+1;elser=mid-1;}f[l]=b[i];}printf("%d\n",len);}return 0;}
没有效率的没有效率。。。
好吧我以后尽量不在题解里吐槽了。。。
做完nlogn的lis当然马上就要用lis在nlogn时间里求lcs了呀。。
————————————————以下为题解——————————————————————————————-————————————————————————
在James W. Hunt和Thomas G. Szymansky 的论文"A Fast Algorithm for Computing Longest Common Subsequence"中,给出了O(nlogn)下限的一种算法。
定理:设序列A长度为n,{A(i)},序列B长度为m,{B(i)},考虑A中所有元素在B中的序号,即A某元素在B的序号为{Pk1,Pk2,..},将这些序号按照降序排列,然后按照A中的顺序得到一个新序列,此新序列的最长严格递增子序列即对应为A、B的最长公共子序列。
举例来说,A={a,b,c,d,b},B={b,c,a,b},则a对应在B的序号为2,b对应序号为{4,0},c对应序号为1,d对应为空集,生成的新序列为{2,4, 0, 1, 4, 0},其最长严格递增子序列为{0,1,4},对应的公共子序列为{b, c, b}
原论文的证明过程较复杂,其实可以简单的通过一一对应来证明。即证明A、B的一个公共子序列和新序列的一个严格递增子序列一一对应。
(1) A、B的一个公共子序列对应新序列的一个严格递增子序列
假设A、B的某一个公共子序列长度为k,则其公共子序列在A和B中可以写为
{Ai1,Ai2, ..., Aik}
{Bj1,Bj2, ..., Bjk}
如此有Ai1 = Aj1,Ai2 = Aj2, ...., Aik = Ajk, 考虑元素Bj1在B中的序号P(Bj1),则有
P(Bj1)< P(Bj2) < ... < P(Bjk)
注意此严格递增子序列属于新序列的一个子序列,因此得证
(2) 新序列的一个严格递增子序列对应A、B的一个公共子序列
设新序列的一个严格递增子序列{P1,P2, ..., Pk},任意两个相信的P不可能属于A中同一个元素,因为A中某元素在B中的序号按照降序排列,但此序列为严格递增序列,矛盾。所以每个P均对应于A中不同位置的元素,设为{Ai1, Ai2, ..., Aik}。
因为P是严格递增序列,则每个P也对应B中唯一的一个元素,假设为{Bj1,Bj2, ..., Bjk},由P的定义可知Ai1= Aj1, Ai2 = Aj2, ...., Aik = Ajk,因此得证。
实现上比较复杂,有以下几个步骤:
(1) 对序列B排序
(2) 计算A中每个元素在B中的序号,并构成新序列
(3) 使用LIS的方法计算最长严格递增子序列
(4) 获取最长公共子序列
- 最长公共子序列的nlogn算法——bsoj1139
- 最长公共子序列nlogn算法
- 最长公共子序列的NlogN解法
- 最长公共子序列(nlogn)
- lcs 最长公共子序列 O(nlogn)算法
- 最长公共子序列 (lcs)O(nlogn)算法
- 算法导论—最长公共子序列
- 算法导论—最长公共子序列
- 最长公共子序列及最长递增子序列NlogN算法及路径记录
- 最长公共子序列O(nlogn)
- uva 10635(最长公共子序列nlogn)
- P3402 最长公共子序列(nlogn)
- 算法序列——最长公共子序列
- nlogn的最长上升子序列的算法(LIS)
- 最长公共子序列的算法
- 最长公共子序列和的 算法
- 最长上升子序列(LIS)长度的O(nlogn)算法
- 最长上升子序列的nlogn算法实现(用栈)
- https://localhost:1158/em cant' establish a connection to the server at localhost:1158.
- Linux文件查找命令find,xargs详述
- 架构设计 例子和实践 系统设计说明书
- 9:00 Studio系列文章之---午夜GPU(五)
- ProcessBuilder 和 Runtime
- 最长公共子序列的nlogn算法——bsoj1139
- uva 10037 - Bridge(贪心)
- UIApplicationDelegate-委托方法浅析
- 数据库Sharding的基本思想和切分策略
- 【C语言学习笔记】qsort函数总结
- 算笔账:养老保险应该少交还是多交
- verilog语言中的@什么意思 verilog语言中的@什么意思
- 跨年倒数,和同事打火锅,元旦放假一天,哪也不想去,呆在家里看电视!
- 去掉warning C4786警告