O(nlogn)LIS及LCS算法
morestep学长出题,考验我们,第二题裸题但是数据范围令人无奈,考试失利之后,刻意去学习了下优化的算法
一、O(nlogn)的LIS(最长上升子序列)
设当前已经求出的最长上升子序列长度为len。先判断A[t]与D[len]。若A [t] > D[len],则将A[t]接在D[len]后将得到一个更长的上升子序列,len = len + 1, D[len] = A [t];否则,在D[1]..D[len]中,找到最大的j,满足D[j] < A[t]。令k = j + 1,则有A [t] <= D[k],将A[t]接在D[j]后将得到一个更长的上升子序列,更新D[k]
= A[t]。
不过这种方法要注意,D[]中并不是我们所求的最长上升子序列
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; int search(int *a,int len,int n)
{
int right=len,left=0,mid=(left+right)/2;
while(left<=right)
{
if (n>a[mid]) left=mid+1;
else if (n<a[mid]) right=mid-1;
else return mid;
mid=(left+right)/2;
}
return left;
}//二分查找 int main()
{
int a[1000]={0},b[1000]={0};
int n,i,j,mid,len;//len用来储存每次循环结束后已经求出值的元素的最大下标
scanf("%d",&n);
for (i=1; i<=n; i++)
scanf("%d",&a[i]);
b[1]=a[1];
b[0]=-1;
len=1;//从第一位开始,目前只有第一位,所以len=1
for (i=1;i<=n;i++)
{
j=search(b,len,a[i]);
b[j]=a[i];
if (j>len) len=j;//更新len,由二分查找可知 ,len其实只须+1.....
}
printf("%d",len);
return 0;
}
二、O(nlogn)的LCS
其实就是把两个序列化成一个序列,然后做一遍上述O(nlogn)的LIS即可
转换方法如下:
有样例
7 8
1 7 5 4 8 3 9
1 4 3 5 6 2 8 9
数组a中 1 2 3 4 5 6 7
分别对应1 7 5 4 8 3 9 不妨在数组b中的相同的数用在数组a中的 下标来表示(没有出现的用0)
由上述描述则数组b原来为: 1 4 3 5 6 2 8 9
可以表示为: 1 4 6 3 0 0 5 7
然后对处理后的数组进行一遍LIS,LIS中的len即为所求
注意:这种O(nlogn)的LCS只适用于两两互不相同的两个序列之中,不然会退化(但可以维护二叉搜索树,然而我并不会/(ㄒoㄒ)/~~),但这种LIS是可重的
下面是代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[100000]={0},c[100000]={0},d[100000]={0}; int search(int *a,int len,int n)
{
int right=len,left=0,mid=(left+right)/2;
while(left<=right)
{
if (n>a[mid]) left=mid+1;
else if (n<a[mid]) right=mid-1;
else return mid;
mid=(left+right)/2;
}
return left;
}//二分查找 int main()
{
int n,m,i,j,mid,len;
scanf("%d%d",&n,&m);
for (i=1; i<=n; i++)
{
scanf("%d",&a[i]);
c[a[i]]=i;
}
for (i=1; i<=m; i++)
{
scanf("%d",&a[i]);
a[i]=c[a[i]];
}
d[1]=a[1];
d[0]=-1;
len=1;
for (i=1;i<=m;i++)
{
j=search(d,len,a[i]);
d[j]=a[i];
if (j>len) len=j;
}
printf("%d",len);
return 0;
}
此处感谢morestep学长的倾情讲解
O(nlogn)LIS及LCS算法的更多相关文章
- O(nlogn)实现LCS与LIS
序: LIS与LCS分别是求一个序列的最长不下降序列序列与两个序列的最长公共子序列. 朴素法都可以以O(n^2)实现. LCS借助LIS实现O(nlogn)的复杂度,而LIS则是通过二分搜索将复杂度从 ...
- LIS和LCS LCIS
首先介绍一下LIS和LCS的DP解法O(N^2) LCS:两个有序序列a和b,求他们公共子序列的最大长度 我们定义一个数组DP[i][j],表示的是a的前i项和b的前j项的最大公共子序列的长度,那么由 ...
- nlogn LIS模板
nlogn 模板 最长上升 #include<bits/stdc++.h> using namespace std; ; int n,x,y,a[N],num[N],d[N],len; / ...
- LCS算法
转自:http://hzzy-010.blog.163.com/blog/static/79692381200872024242126/ 好详细~~~也十分好理解~~~ 最长公共子序列问题(非连续的 ...
- 关于LIS和LCS问题的o(nlogn)解法
o(n^2)解法就不赘述了,直接解释o(nlogn)解法 LIS最长递增子序列: 先明确一个结论:在长度最大为len的递增序列里若末尾元素越小,该递增序列越容易和后面的子序列构造出一个更长的递增子序列 ...
- LIS与LCS的nlogn解法
LIS(nlogn) #include<iostream> #include<cstdio> using namespace std; ; int a[maxn]; int n ...
- LIS的优化算法O(n log n)
LIS的nlogn的优化:LIS的优化说白了其实是贪心算法,比如说让你求一个最长上升子序列把,一起走一遍. 比如说(4, 2, 3, 1, 2,3,5)这个序列,求他的最长上升子序列,那么来看,如果求 ...
- LCS 算法实现
动态规划算法 #include <iostream> #include <string.h> #include <algorithm> #include <m ...
- Levenshtein Distance + LCS 算法计算两个字符串的相似度
//LD最短编辑路径算法 public static int LevenshteinDistance(string source, string target) { int cell = source ...
随机推荐
- tree命令的使用
有些工作在linux下完成就是比在windows下完成高效! windows和linux都有tree命令,主要功能是创建文件列表,将所有文件以树的形式列出来 windows下的tree比较垃圾,只有两 ...
- Java集合系列:-----------04fail-fast总结(通过ArrayList来说明fail-fast的原理以及解决办法)
前面,我们已经学习了ArrayList.接下来,我们以ArrayList为例,对Iterator的fail-fast机制进行了解.内容包括::1 fail-fast简介2 fail-fast示例3 f ...
- c#socket编程基础
Microsoft.Net Framework为应用程序访问Internet提供了分层的.可扩展的以及受管辖的网络服务,其名字空间System.Net和System.Net.Sockets包含丰富的类 ...
- Paxos变种和优化
分布式系统理论进阶 - Paxos变种和优化 引言 <分布式系统理论进阶 - Paxos>中我们了解了Basic Paxos.Multi Paxos的基本原理,但如果想把Paxos应用于工 ...
- 使用LocalBroadcastManager
Android中BroadcastReceiver主要用途有 发送通知,更新UI或者数据,应用程序间相互通信,监听系统状态(比如开机,网络等) Android中BroadcasetReceiver的注 ...
- JSON简介以及用法汇总
什么是JSON? JavaScript 对象表示法(JavaScript Object Notation). JSON是一种轻量级的数据交换格式,某个JSON格式的文件内部譬如可以长成这样: { &q ...
- .net程序员转行做手游开发经历(四)
今天是大年初二,在这里先给大家拜个年,祝大家在新的一年里能事事顺心. 年前的时候更新了一版,先发了内测,没有想到过年这几天,有的小伙伴们还在玩,还给我们提了很多建议和意见,让我们觉得非常温暖,给我们很 ...
- 系统升级日记(2)- 升级到SharePoint Server 2013
最近一段时间在公司忙于将各类系统进行升级,其最主要的目标有两个,一个是将TFS2010升级到TFS2013,另外一个是将SharePoint 2010升级到SharePoint 2013.本记录旨在记 ...
- 阿里巴巴高新能数据源com.alibaba.druid.pool.DruidDataSource的jar包配置
aspectjweaver-1.7.4.jar druid-0.2.9.jar 两个包,用于提供com.alibaba.druid.pool.DruidDataSource
- Ceph: validate that the RBD cache is active
Ceph: validate that the RBD cache is active Quick and simple test to validate if the RBD cache is en ...