上次TYVJ有一道裸LIS,然而我当时直接打了一个N^2暴力就草草了事,然后就ZZ了,只拿了60分,其实NlogN的LIS和N^2的差的不多,只是没有N^2,好想罢了,鉴于某学弟的要求,所以就重现一下金哥当年讲LIS的风范。

  首先,LIS指的是最长上升子序列。指的是我们要求出一个在母序列中找出一些元素,在保证这个子序列上升的同时,保证这个序列是整个母序列里满足这一要求的最长序列。

  那么我们可以直接这样想,我们要保证当前所拼接的链最大,那么对于每一个元素来说,可以直接一遍循环判断它能够属于哪一个链,使当前以这个元素为结尾的链所接的元素个数最多,也就是所得的结果越大。

  那么对于一个元素ai,可以直接找a1到ai-1的元素中ai链在哪一个元素所得解最优,最优解放在f[i]里,这种对于所有情况的判断,很明显是DP,那么,转移方程就是:f[i]=a[j]<a[i]?max(f[j]+1,f[i]):f[i]

  那么明显的,这是一个N^2的算法,对于每一个元素要求以前是否有能够找到更优解的上一步元素,一个判断N遍。

  那如何得到一个更优算法捏?

  其实很简单,让我们先回顾刚才我们所做的操作,我们对于当前的一个元素,找前面所算过的所有结果,试图找出更优解。我们在做这一工作时,也找了很多肯定不为最优解的元素,这是一件很浪费的事情,那么我们可以找一个优化这一过程的方法。

  我们知道,对于任意一个元素,使它的解更优的方案肯定是a[i]小,并且f[i]大的一个理想元素,因为对于这样的一个理想元素,才可能使后面的解更优,而最大的f[i]是有限的,所以,我们很轻易得想到一个优化方法:

  使用一个数组d,用d[i]记录当前  f[i]  为  i  的  a[i]最小的元素,d随着元素的向后递推逐渐维护。

  开一个数组就能使LIS更优吗?答案是当然的,原因很简单,我们发现,我们所维护的这个d数组是递增的,这一结论可以通过反证法易证。既然这一数组是递增的,我们就可以轻易的通过二分来得到最优解。

  所以,对于每一个元素做一遍二分,显而易见复杂度是nlogn的。

附上一道水题 codevs

LIS问题是最经典的动态规划基础问题之一。如果要求一个满足一定条件的最长上升子序列,你还能解决吗?

给出一个长度为N整数序列,请求出它的包含第K个元素的最长上升子序列。

例如:对于长度为6的序列<2,7,3,4,8,5>,它的最长上升子序列为<2,3,4,5>,但如果限制一定要包含第2个元素,那么满足此要求的最长上升子序列就只能是<2,7,8>了。

输入描述 Input Description

第一行为两个整数N,K,如上所述。

接下来是N个整数,描述一个序列。

输出描述 Output Description

请输出两个整数,即包含第K个元素的最长上升子序列长度。

样例输入 Sample Input

8 6

65 158 170 299 300 155 207 389

样例输出 Sample Output

4

数据范围及提示 Data Size & Hint

80%的数据,满足0<n<=1000,0<k<=n

    100%的数据,满足0<n<=200000,0<k<=n

 #include<stdio.h>
int cnt,n,a[],best[];
void push(int x)
{
int L=,R=cnt;
int mid;
while(L<=R)
{
mid=(L+R)/;
if(x>best[mid]){
L=mid+;
if(best[L]>x)best[L]=x;
}
else R=mid-;
}
}
int main()
{
int k,i;
scanf("%d%d",&n,&k);k--;
for(i=;i<=n-;i++)
{
scanf("%d",&a[i]);
if(i>k&&a[i]<=a[k]){i--;n--;
}
}
for(i=;i<=k-;i++)
if(a[i]>=a[k])a[i]=;
for(i=;i<=n-;i++)
{
if(a[i]<best[cnt]&&a[i])push(a[i]);
else if(a[i])best[++cnt]=a[i];
}
printf("%d",cnt);
return ;
}

算法描述》关于LIS的nlogn方法的更多相关文章

  1. 算法进阶 (LIS变形) 固定长度截取求最长不下降子序列【动态规划】【树状数组】

    先学习下LIS最长上升子序列 ​ 看了大佬的文章OTZ:最长上升子序列 (LIS) 详解+例题模板 (全),其中包含普通O(n)算法*和以LIS长度及末尾元素成立数组的普通O(nlogn)算法,当然还 ...

  2. BZOJ 1609 [Usaco2008 Feb]Eating Together麻烦的聚餐:LIS & LDS (nlogn)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1609 题意: 给你一个只由数字"1,2,3"组成的序列a[i],共n个 ...

  3. 第四十四个知识点:在ECC密码学方案中,描述一些基本的防御方法

    第四十四个知识点:在ECC密码学方案中,描述一些基本的防御方法 原文地址:http://bristolcrypto.blogspot.com/2015/08/52-things-number-44-d ...

  4. 海量数据挖掘MMDS week2: 频繁项集挖掘 Apriori算法的改进:非hash方法

    http://blog.csdn.net/pipisorry/article/details/48914067 海量数据挖掘Mining Massive Datasets(MMDs) -Jure Le ...

  5. 迪杰斯特拉(Dijkstra)算法描述及理解

    Dijkstra算法是一种计算单源最短无负边路径问题的常用算法之一,时间复杂度为O(n2) 算法描述如下:dis[v]表示s到v的距离,pre[v]为v的前驱结点,用以输出路径,vis[v]表示该点最 ...

  6. 算法描述》LCA两三事(蒟蒻向)

    LCA是图论中常用的解决树形结构子问题的工具,这一问题一般需要用一个简短的子函数直接解决,但是这对于广大蒟蒻们仍然是一个不小的问题. LCA是指在树形结构中两点的最近公共祖先,对于这个问题,直接向上找 ...

  7. 最长上升子序列(LIS)nlogn模板

    参考https://www.cnblogs.com/yuelian/p/8745807.html 注意最长上升子序列用lower_bound,最长不下降子序列用upper_bound 比如123458 ...

  8. LIS(nlogn)算法描述//线性DP经典类型

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

  9. 算法心得1:由$nlogn$复杂度的LIS算法引起的思考

    LIS(Longest Increasing Subsequence)是一类典型的动态规划类问题,简化描述如下: 给定$N(n) = \{1,2...,n\}$的一个排列$P(n)$,求$P(n)$中 ...

随机推荐

  1. php小练习——实现几种不同的金字塔

    首先,从简单的着手,打印出金字塔的右半部分,代码如下 <?php $n=5; //金字塔行数 //外层的for循环控制层数 for($i=1;$i<=$n;$i++){ //内层的for循 ...

  2. (效果二)js实现两个变量值的交换

    ES5: var a = 12,b=13,c; c = a; a = b; b = c; console.log(a,b);//13,12 通过设置第三方变量交换赋值来实现   ES6 var a = ...

  3. PHPCMS V9调用父栏目 顶级父栏目的代码

    一.调用父栏目 首先是列表页和二级栏目页list.html {$CATEGORYS[$top_parentid][catname]} //顶级父栏目名称 {$CATEGORYS[$CAT[parent ...

  4. 后台导入导出Excel

    Excel导出 定义数据模型 参考财付通的批量提现Excel的格式,定义模型如下 private int recordId; //提现id private String cname; //提现人名称 ...

  5. 关于 self = [super init];

    [plain] view plaincopyprint? - (id)init { self = [super init]; // Call a designated initializer here ...

  6. 常用的文件数据类型mime

    有时在编程中会用到文件的类型,比如http的请求或相应header头信息,文件上传时自定义头信息等. ai application/postscript aif audio/x-aiff aifc a ...

  7. 在Toad中导入导出数据

    一.导出数据 右键点击所要导出的表名,选择“Export   Date”     二.导入数据   一.右键点击表名,选择“import  date” 二.下一步 三.下一步 四.下一步 在oracl ...

  8. (装)Android杂谈--禁止TimePicker控件通过keyboard输入

    Android 4.1版本以上用的是类似与ios的滚动时间控件,但是4.1以下,用的TimePicker确实通过点击上下按钮来更改时间的,虽然也提供了编辑框编辑,但是可能会超出编辑范围 如果要禁止编辑 ...

  9. SQL Server数据库优化经验总结

    优化数据库的注意事项: 1.关键字段建立索引. 2.使用存储过程,它使SQL变得更加灵活和高效. 3.备份数据库和清除垃圾数据. 4.SQL语句语法的优化.(可以用Sybase的SQL Expert, ...

  10. RHEL6.2配置从零开始

    RHEL6.2最小化安装并配置,持续更新中... 1.RHEL6.2最小化安装 RHEL6.2默认安装许多用不到的软件,不仅浪费空间.增大系统开销,还会显得凌乱.所以选择最小化安装.  注意:安装步骤 ...