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 ...
随机推荐
- DefaultFilesMiddleware中间件如何显示默认页面
DefaultFilesMiddleware中间件如何显示默认页面 DefaultFilesMiddleware中间件的目的在于将目标目录下的默认文件作为响应内容.我们知道,如果直接请求的就是这个默认 ...
- 毫米转换为PX
公式:毫米数/25.4*你的电脑的DPI,win7 DPI 100%缩放为96,125%为120,150%为144,200%为192 象素数 / DPI = 英寸数 英寸数 * 25.4 = 毫米数
- SUBLIME TEXT 2中,光标移入移出括号的快捷键设置
无赖右方向键→和End键都在键盘的另一边,每次输入完一个函数,光标在各种括号中间,有什么更好的方式将光标移出来呢?在Sublime Text 2中,我们可以自己设置快捷键: { "keys& ...
- 我的 GitHub 100 连击
终于达成 gayhub 的第一个100连击了,感觉自己整个人颜色都不一样了,完全蜕变了. PS: GitHub 汉化插件 52cik/github-hans 感兴趣的赶紧 get 起来吧. 遇到瓶颈 ...
- js的this什么时候会出现报错
var aa ={ name:"boy", age:, like: function(){ console.log(this.name); } } //aa.like();//这样 ...
- 记一次在Linux上面启动部署在tomcat服务器的程序
前提:Linux系统已安装好jre环境 1.文件结构: 文件说明: 部署文件包含以下文件:1.apache-tomcat-7 程序运行的应用服务器tomcat包含: war包:apache-tomc ...
- 利用ZTree链接数据库实现 [权限管理]
最近想研究权限管理,看群里有人发了ZTrees模板,我看了下,觉得笔easyUI操作起来更灵活些,于是就开始研究了. 刚开始从网上找了找了个Demo,当然这个并没有实现权限啥的,但实现了前台调用Aja ...
- 2015年辽宁省赛Interesting Tree
题目描述 Recently, Miss Huang want to receive a Tree as her birthday gift! (What a interesting person!) ...
- ElasticSearch入门系列(四)分布式初探
序言:ElasticSearch致力于隐藏分布式系统的复杂性,以下的操作都是在底层自动完成的: 将你的文档分区到不同的容器或者分片(shards),他们可以存在于一个或多个节点中 将分片均匀的分配到各 ...
- C# 对sharepoint 列表的一些基本操作,包括添加/删除/查询/上传文件给sharepoint list添加数据
转载:http://www.cnblogs.com/kivenhou/archive/2013/02/22/2921954.html 操作List前请设置SPWeb的allowUnsafeUpdate ...