首页 > 其他分享 >LIS最长上升子序列

LIS最长上升子序列

时间:2023-01-23 21:45:42浏览次数:46  
标签:int LIS len ans 序列 上升 最长

一种方法是O(Nˆ2)的DP

主要是O(NlogN)的DP

最长上升子序列,最长不下降子序列,最长下降子序列,最长不上升子序列都同理

 

以LIS最长上升子序列为例

DP思路:

总的来说,我们要求以 i为结尾,最长的上升子序列的长度

现在到了第 i 个数,那么前面的 1~i-1的数都已经处理完毕了

设 f[x] 表示以 长度x的上升子序列中,子序列末端的最优值 ,此处f[x]就是保持最小值

比如 1,2,3,4 (5) 现在到了5,1~4都已经处理完毕,则长度为 3 的上升子序列的最优值是 3,不是4,f[3]=3

那么这有个巧妙的结论,f[x]一定是单调递增的,理解理解

1~i-1都已经处理完毕,对于 i 结尾的最长上升子序列,我们要找到最后一个小于 a[i] 的 f[x],那么对于 i 结尾的最长上升子序列的长度就是 x+1;

这过程可用二分处理,然后更新f[x+1],使得f[x+1]始终保持最优值。

    ans=0;
    memset(f,0,sizeof(f));
    for(int i=1;i<=n;i++)
    {
        if(!ans) { ans=1,f[1]=a[1];continue; }
        int l=1,r=ans;
        while(l+1<r)
        {
            int mid=(l+r)/2;
            if(f[mid]<a[i]) l=mid;
            else r=mid; 
        }
        int len;
        if(f[r]<a[i]) len=r;
        else if(f[l]<a[i]) len=l;
        else len=0;
        if(!f[len+1]) f[len+1]=a[i];
        else f[len+1]=min(f[len+1],a[i]);
        if(len+1>ans) ans=len+1; 
    }
    printf("%d\n",ans);

 

 

那么以最长不上升子序列为例,f[x]是单调递减的,我们要找最后一个大于等于 a[i]  的 f[x]

f[x]要保持最优解,就是始终保持最大值。

    int ans=0;
    for(int i=1;i<=n;i++)
    {
        if(!ans) { ans=1,f[1]=a[1];continue; }
        int l=1,r=ans;
        while(l+1<r)
        {
            int mid=(l+r)/2;
            if(f[mid]>=a[i]) l=mid;
            else r=mid; 
        }
        int len;
        if(f[r]>=a[i]) len=r;
        else if(f[l]>=a[i]) len=l;
        else len=0;
        f[len+1]=max(f[len+1],a[i]);
        if(len+1>ans) ans=len+1; 
    }
    printf("%d\n",ans);

 

 

例题:

P1020 [NOIP1999 普及组] 导弹拦截 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

题目简化:

给定一个数列 b,问:

  1. 它的最长不上升子序列长度;
  2. 最少能被划分成多少个不上升子序列。

1.就不说了

2. Dilworth 定理 :最少的不上升子序列的个数就是最长上升子序列的长度 (记住就好)

标签:int,LIS,len,ans,序列,上升,最长
From: https://www.cnblogs.com/Willette/p/17065557.html

相关文章

  • spring boot——请求与参数校验——重要概念——配置Servlet、Filter、Listener——代
          代码配置:packageorg.example.webFilter.config;importorg.example.webFilter.filter.FirstFilter;importorg.example.webFilter.listener.Firs......
  • 2816. 判断子序列
    文章目录​​Question​​​​Ideas​​​​Code​​Question给定一个长度为n的整数序列a1,a2,…,an以及一个长度为m的整数序列b1,b2,…,bm。请你判断a序列是否为......
  • Java反序列化-CommonsCollections2利用链分析
    前言接上篇TemplatesImpl利用链分析,学习了通过TemplatesImpl利用链来进行类加载执行恶意代码,现在来学习一下CommonsCollections2利用链。分析前的准备漏洞组件:commons-c......
  • LeetCode最长回文子串(/dp)
    原题解题目约束解法解法一#include<iostream>#include<string>#include<vector>usingnamespacestd;classSolution{public:stringlongestPa......
  • dart遍历的时候操作list
    实际上,在遍历的时候,list对应的内存是被锁住的Listlist=[1,2,3,4];//这里使用了箭头函数,后面的表达式为true时会删除当前值list.removeWhere((value)=>value=......
  • 【双指针】LeetCode 409. 最长回文串
    题目链接409.最长回文串思路遍历字符串过程中统计字符出现个数,如果达到2则说明可以放到回文串的两端,需要result+=2。遍历完之后的回文串如果长度小于s,说明s中存......
  • 序列凑零(冬季每日一题 35)
    给定一个长度为的整数序列。所有都是非零整数并且绝对值不超过。另外,现在,请你构造另一个整数序列,使得要求,所有都是非零整数并且绝对值不超过。输入格式第一行包......
  • 8种时间序列分类方法总结
    对时间序列进行分类是应用机器和深度学习模型的常见任务之一。本篇文章将涵盖8种类型的时间序列分类方法。这包括从简单的基于距离或间隔的方法到使用深度神经网络的方法......
  • java读取Excel成List对象数组
    文件IO是任何软件进行的重要组成部分,我们在电脑上创建一个Excel文件,然后打开它修改一些东西或者删除它。Java给我们提供了操纵文件的很多工具类,本文主要是使用POI操纵Excel......
  • Lisp的求值规则
    Lisp的求值规则有些例子以scheme为例,不过大多在lisp都是通用的lisp几乎所有类型都可以被求值。数据类型的值:数的值就是它本身(它抽象概念上代表的那个数)。字符......