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. wireshake抓包,飞秋发送信息,python

    http://wenku.baidu.com/link?url=Xze_JY8T15pqI9mBLRpTxWF2d6MP-32xb6UwuE6tsUmitRDheJe-Ju87WlDEDBGuI5MF ...

  2. selmodel

    selmodel不仅可以设置checkbox,还可以设置单元格选中模式,列选择模式,行选择模式

  3. Apache Rewrite 拟静态配置

    1.mod_rewrite 简介和配置 Rewirte主要的功能就是实现URL的跳转和隐藏真实地址,基于Perl语言的正则表达式规范.平时帮助我们实现拟静态,拟目录,域名跳转,防止盗链等 2.mod_ ...

  4. 推薦使用 Microsoft Anti-Cross Site Scripting Library v3.1

    原文链接:http://blog.miniasp.com/post/2009/09/27/Recommand-Microsoft-Anti-XSS-Library-V31.aspx 雖然我之前已經寫過 ...

  5. 安装Ubuntu时的硬盘分区方案

    如果你准备在硬盘里只安装Ubuntu一个操作系统的话,建议你采用一个“/”.一个“swap”和一个“/home”的三分区方案:/ :10GB-15GB.swap:物理内存小于或等于 512MB,建议分 ...

  6. JPEG格式

    Jpg文件格式[参考] 微处理机中的存放顺序有正序(big endian)和逆序(little endian)之分.正序存放就是高字节存放在前低字节在后,而逆序存放就是低字节在前高字节在后.例如,十六 ...

  7. 路由信息协议(RIP)的防环机制

    防环机制 1-记数最大值(maximum hop count):定义最大跳数(最大为15跳),当跳数为16跳时,目标为不可达. 2-水平分割(split horizon):从一个接口学习到的路由不会再 ...

  8. mysql的主从复制是如何实现的

    前言 MySQL的主从复制是MySQL本身自带的一个功能,不需要额外的第三方软件就可以实现,其复制功能并不是copy文件来实现的,而是借助binlog日志文件里面的SQL命令实现的主从复制,可以理解为 ...

  9. C# 属性、索引

    属性(property): public string Name { get { return _name; } set { _name = value; } } 简写为: public string ...

  10. canvas拖动

    var canvas=document.getElementById("canvas"); var cxt=canvas.getContext("2d"); v ...