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算法的更多相关文章

  1. O(nlogn)实现LCS与LIS

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

  2. LIS和LCS LCIS

    首先介绍一下LIS和LCS的DP解法O(N^2) LCS:两个有序序列a和b,求他们公共子序列的最大长度 我们定义一个数组DP[i][j],表示的是a的前i项和b的前j项的最大公共子序列的长度,那么由 ...

  3. nlogn LIS模板

    nlogn 模板 最长上升 #include<bits/stdc++.h> using namespace std; ; int n,x,y,a[N],num[N],d[N],len; / ...

  4. LCS算法

    转自:http://hzzy-010.blog.163.com/blog/static/79692381200872024242126/  好详细~~~也十分好理解~~~ 最长公共子序列问题(非连续的 ...

  5. 关于LIS和LCS问题的o(nlogn)解法

    o(n^2)解法就不赘述了,直接解释o(nlogn)解法 LIS最长递增子序列: 先明确一个结论:在长度最大为len的递增序列里若末尾元素越小,该递增序列越容易和后面的子序列构造出一个更长的递增子序列 ...

  6. LIS与LCS的nlogn解法

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

  7. LIS的优化算法O(n log n)

    LIS的nlogn的优化:LIS的优化说白了其实是贪心算法,比如说让你求一个最长上升子序列把,一起走一遍. 比如说(4, 2, 3, 1, 2,3,5)这个序列,求他的最长上升子序列,那么来看,如果求 ...

  8. LCS 算法实现

    动态规划算法 #include <iostream> #include <string.h> #include <algorithm> #include <m ...

  9. Levenshtein Distance + LCS 算法计算两个字符串的相似度

    //LD最短编辑路径算法 public static int LevenshteinDistance(string source, string target) { int cell = source ...

随机推荐

  1. 见鬼了,swiper

    1.今天不知怎么swiper的onInit函数不起作用,怎么弄都不行: 把以前能行的案例的包都导进去还是不行,但是onSlideChangeEnd可以触发,晕死了.... 不,它触发了一次onInit ...

  2. ACA烤箱菜单各项温度

    说明书找不到了, 网上找到的各项温度说明, 记一个备用 casserole 218度 cake 171度 backery 177度 frozen food 238度 patato 232度 roast ...

  3. Entity Framework连接Mysql数据库并生成Model和DAL层

    Entity Framework (EF,ADO.NET Entity Framework)是微软官方提供的.NET平台的ORM框架.相比于LINQ TO SQL,EF框架具有很明显的优势: EF框架 ...

  4. ASP.NET MVC 教程-MVC简介

    ASP.NET 是一个使用 HTML.CSS.JavaScript 和服务器脚本创建网页和网站的开发框架. ASP.NET 支持三种不同的开发模式:Web Pages(Web 页面).MVC(Mode ...

  5. 学习C++.Primer.Plus 8 函数探幽

    1. 内联函数 普通函数调用: 存储调用指令的地址->将函数参数复制到堆栈->跳到函数地址执行代码(返回值放到寄存器)->跳回调用指令处 2.  当代码执行时间很短,且会被大量调用的 ...

  6. Alpha版本发布说明

    软件发布的同时,在团队博客上写一个发布说明     ▪ 列出这一版本的新功能     ▪ 这一版本修复的缺陷     ▪ 对运行环境的要求     ▪ 安装方法     ▪ 描述系统已知的问题和限制 ...

  7. MFC 调试方法

    AfxDebugBreak     MFC 提供特殊的 AfxDebugBreak 函数,以供在源代码中对断点进行硬编码:     AfxDebugBreak( ); 在 Intel 平台上,AfxD ...

  8. PHP 基础笔记

    数据类型 字符串 整数 浮点数 布尔值 数组 对象 NULL 未定义的变量,数据类型为 NULL. PHP 中数组和对象是不同的类型,而 js 中数组即为对象.(ps: es6 已经内置了 class ...

  9. VS2010+MVC4+Spring.NET2+NHibernate4-传统三层架构-前篇

    VS2010+MVC4+Spring.NET2+NHibernate4 - 传统三层架构 - 前篇 一直追求使用开源项目,就因一个字:懒! 一直想整理一下的,却一直懒到现在!从当初用的MVC3到现在的 ...

  10. DLL编写教程

    本文对通用的DLL技术做了一个总结,并提供了源代码打包下载,下载地址为: http://www.blogjava.net/Files/wxb_nudt/DLL_SRC.rar   DLL的优点 简单的 ...