o(n^2)解法就不赘述了,直接解释o(nlogn)解法

LIS最长递增子序列;

先明确一个结论:在长度最大为len的递增序列里若末尾元素越小,该递增序列越容易和后面的子序列构造出一个更长的递增子序列。也即认为,长度为len的递增子序列中末尾元素最小的那种最需要保留。我们不妨称这个目前找到序列为到目前为止的 最优序列。

因此设置一个数组lis[i]其中 i 表示此时最大递增序列的长度,数组值表示此时达到 i 的最优序列(也即 长度为len的递增子序列中末尾元素最小的那种)的末尾元素。

那么此时只需遍历一遍输入数据,维护lis的上述特性,则最后所得的lis数组的长度就是要求的len。

不多言,结合代码理解:

  1. #include<iostream>
  2. #include<cstdio>
  3. using namespace std;
  4. const int maxn=1e5+;
  5. int a[maxn];
  6. int n;
  7. int lis[maxn];
  8. int len=;
  9. int find(int x){
  10. int l=,r=len,m;
  11. while(l<r){
  12. m=l+(r-l)/;
  13. if(lis[m]>=a[x]){//这里若去掉等号即为 非严格递增序列
  14. r=m;
  15. }
  16. else{
  17. l=m+;
  18. }
  19. }
  20. return l;
  21. }
  22. int main(void){
  23. scanf("%d",&n);
  24. for(int i=;i<=n;i++)scanf("%d",&a[i]);
  25. lis[]=a[];
  26. for(int i=;i<=n;i++){
  27. if(a[i]>lis[len]){
  28. lis[++len]=a[i];
  29. }
  30. else{
  31. int pos=find(i);
  32. lis[pos]=a[i];
  33. }
  34. }
  35. printf("%d",len);
  36. return ;
  37. }

LCS最长公共子序列:

最长公共子序列 的 nlogn 的算法本质是 将该问题转化成 最长增序列(LIS),因为 LIS 可以用nlogn实现,所以求LCS的时间复杂度降低为 nlogn。

假设有两个序列 s1[ 1~6 ] = { a, b, c , a, d, c }, s2[ 1~7 ] = { c, a, b, e, d, a, b }。

记录s1中每个元素在s2中出现的位置, 再将位置按降序排列, 则上面的例子可表示为:

loc( a)= { 6, 2 }, loc( b ) = { 7, 3 }, loc( c ) = { 1 }, loc( d ) = { 5 }。

将s1中每个元素的位置按s1中元素的顺序排列成一个序列s3 = { 6, 2, 7, 3, 1, 6, 2, 5, 1 }。

在对s3求LIS得到的值即为求LCS的答案。(这点我也只是大致理解,读者可以自己理解甚至证明。)

这里给出全排列情况下的代码(即两个序列长度相同,数字组成相同,无重复元素)

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. using namespace std;
  5. const int maxn=1e6+;
  6. int n,len=;
  7. int lis[maxn];
  8. int a[maxn];
  9. int b[maxn];
  10. int loc[maxn];
  11. int find(int x){
  12. int l=,r=len,m;
  13. while(l<r){
  14. m=l+(r-l)/;
  15. //if(lis[m]>=b[x]){//智障错误,找了那么久。。
  16. if(lis[m]>=x){
  17. r=m;
  18. }
  19. else l=m+;
  20. }
  21. return l;
  22. }
  23. int main(void){
  24. scanf("%d",&n);
  25. for(int i=;i<=n;i++)scanf("%d",&a[i]);
  26. for(int i=;i<=n;i++){
  27. scanf("%d",&b[i]);
  28. loc[b[i]]=i;
  29. }
  30. for(int i=;i<=n;i++){
  31. b[i]=loc[a[i]];
  32. }
  33. // for(int i=1;i<=n;i++)printf("%d",b[i]) ;//
  34. // printf("\n");
  35. if(n!=)lis[++len]=b[];
  36. for(int i=;i<=n;i++){
  37. if(b[i]>lis[len]){
  38. lis[++len]=b[i];
  39. }
  40. else{
  41. int pos=find(b[i]);
  42. lis[pos]=b[i];
  43. }
  44. }
  45. printf("%d",len);
  46. return ;
  47. }

关于LIS和LCS问题的o(nlogn)解法的更多相关文章

  1. LIS LCS n^2和nlogn解法 以及LCIS

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

  2. LIS和LCS LCIS

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

  3. O(nlogn)LIS及LCS算法

    morestep学长出题,考验我们,第二题裸题但是数据范围令人无奈,考试失利之后,刻意去学习了下优化的算法 一.O(nlogn)的LIS(最长上升子序列) 设当前已经求出的最长上升子序列长度为len. ...

  4. LIS与LCS的nlogn解法

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

  5. UVa 111 History Grading (简单DP,LIS或LCS)

    题意:题意就是坑,看不大懂么,结果就做不对,如果看懂了就so easy了,给定n个事件,注意的是, 它给的是第i个事件发生在第多少位,并不是像我们想的,第i位是哪个事件,举个例子吧,4 2 3 1, ...

  6. DP---DAG、背包、LIS、LCS

    DP是真的难啊,感觉始终不入门路,还是太弱了┭┮﹏┭┮ DAG上的DP ​ 一般而言,题目中如果存在明显的严格偏序关系,并且求依靠此关系的最大/最小值,那么考虑是求DAG上的最短路或者是最长路.(据说 ...

  7. 【LIC】O(nlogn)解法

    [LIC--最长递增子序列问题] 在一列数中寻找一些数,这些数满足:任意两个数a[i]和a[j],若i<j,必有a[i]<a[j],这样最长的子序列称为最长递增子序列. O(nlogn)算 ...

  8. 拦截导弹nlogn解法

    题目 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国 ...

  9. DP练习 最长上升子序列nlogn解法

    openjudge 百练 2757:最长上升子序列 总时间限制:  2000ms 内存限制:  65536kB 描述 一个数的序列bi,当b1 < b2 < ... < bS的时候, ...

随机推荐

  1. Deploying Cloud Foundry on OpenStack Juno and XenServer (Part II)

    link http://rabbitstack.github.io/deploying-cloud-foundry-on-openstack-juno-and-xenserver-part-ii/ L ...

  2. 数据一致性和io类型

    版权声明:本文由高剑林原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/106 来源:腾云阁 https://www.qclo ...

  3. Excel 2010 如何在Excel的单元格中加入下拉选项

    http://jingyan.baidu.com/article/03b2f78c4ba8a05ea237ae95.html 第一步:打开excel文档,选中需加入下拉选项的单元格.   第二步:点击 ...

  4. Java初学者笔记二:关于类的常见知识点汇总

    一.Java的类: Java的类是Java的基本概念了,基本的定义语法我就不提了,自己也不会忘了的,下面分成几个模块介绍: 1.Java的类定义时候的修饰符 2.Java的类的继承与派生 二.Java ...

  5. iOS5 ARC学习笔记:strong、weak等详解

    2013-03-25 13:41 佚名 oschina 字号:T | T iOS5中加入了新知识,就是ARC,其实我并不是很喜欢它,因为习惯了自己管理内存.但是学习还是很有必要的.现在我们看看iOS5 ...

  6. 微信小程序 --- 绘画

    cavans及context详解 绘画API的使用 游戏的制作

  7. oracle之用户名密码包含特殊字符时候怎么使用sqlplus登录

    oracle有时候用户密码包含一些特殊字符直接登录会报错,需要使用以下方式登录sqlplus sqlplus 'username/"password"' PS:整体使用单引号括起来 ...

  8. What are Traceroute, Ping, Telnet and Nslookup commands?

    https://help.maximumasp.com/KB/a445/connectivity-testing-with-ping-telnet-tracert-and-pathping-.aspx ...

  9. Vanish/squid

    http://www.yl1001.com/article/5291411898652918.htm HTTP加速 简单的说,在本次测试中,Varnish将来自80的请求转发到后端的nginx8080 ...

  10. talib 中文文档(五):文档导航

    Documentation 安装和问题 快速使用 高级应用 方法分类 Overlap Studies 重叠的研究 Momentum Indicators 动量指标 Volume Indicators ...