首页 > 其他分享 >LIS之nlogn做法

LIS之nlogn做法

时间:2022-12-25 10:00:44浏览次数:56  
标签:int len 100001 LIS 序列 做法 nlogn

一.LIS

题目传送门
给定一个长为 \(n\) 的序列 \(a_i\),求这个序列的最长单调上升子序列长度。
\(1\)≤\(a_i\)≤\(n\)≤\(10^5\)

二.解析

\(n^2\)解法在此不再赘述,显然此方法过不了此题,下面考虑\(nlogn\)解法即二分
定义\(f[n]\)为长度为\(n\)的子序列的最后一项的数值,\(len\)为当前的最优解,不难发现\(f[n]\)是单调递增的
对于当前处理的元素\(a[i]\),分为两种情况
1.\(a[i]>f[len]\),此时自然可以直接将\(a[i]\)接在\(len+1\)处,且更新\(f[len+1]\),即\(f[++len]=a[i];\)
2.\(a[i]<=f[len]\),此时无法形成\(len+1\)长的上升子序列,但我们要考虑将短于\(len\)的之前存储过的上升子序列的末项变得更小,这样才更有机会以后向这个序列后接入更多的数。\(f[n]\)是单调的,考虑二分,找到最小的\(f[k]>=a[i]\)用\(a[i]\)更新\(f[k]\)。就是找到一个\(f[k]\),我们可以想象它所代表的一串上升子序列,将末项改小后,仍然使此上升子序列合法。其实,\(f[k]\)都是由\(f[k-1]\)继承而来的,所以\(f[k-1]\)即我们想象里的长度为k的上升子序列的倒数第二项,所以只要将\(a[i]>f[k-1]\)同时\(a[i]<=f[k]\)修改就一定合法。又因为当\(f[k]\)较小时,我们会发现这总归不如修改\(f[b] (b>k)\)来的好,因为末项修改后大家都一样,即以后能装下更多数的潜力是一样的,那么就是当前长度越长越优,并且在以后的使上升子序列变长的过程中,是从最优方案为基础的,不是最优的那些方案也不必修改了。受此二者限制,我们只需找到最小的\(f[k]>=a[i]\)并加以修改即可。此处建议读者手动模拟,深刻理解。

三.AC代码

#include<bits/stdc++.h>
using namespace std;

int main()
{
	int n,a[100001],f[100001],dp[100001];
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        f[i]=0x7fffffff;
    }
    f[1]=a[1];
    int len=1;
    for(int i=2;i<=n;i++)
    {
        int l=0,r=len,mid;
        if(a[i]>f[len])f[++len]=a[i];
        else 
        {
        while(l<r)
        {   
            mid=(l+r)/2;
            if(f[mid]>=a[i])r=mid;
            else l=mid+1; 
        }
        f[l]=min(a[i],f[l]);
        }
    }
    cout<<len<<endl;
	return 0;
}

标签:int,len,100001,LIS,序列,做法,nlogn
From: https://www.cnblogs.com/kezhuo/p/17003505.html

相关文章

  • ListView用法及BaseAdapter详解
    1.先上代码布局部分:items.xml<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout......
  • Docker+Jenkins+Gitee+Node+Vue构建dist包并通过publish over ssh传输到服务器替换重
    场景docker-compose入门以及部署SpringBoot+Vue+Redis+Mysql(前后端分离项目)以若依前后端分离版为例:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/12837......
  • 集合(进阶List系列)
    集合的体系结构Collection体系结构List和Set2种系列的集合特点有序指的是存和取的顺序一样,不是数值从大到小和从小到大排序2种系列的特点正好相反Collection......
  • Razor操作Dropdownlist
    目的:为Dropdownlist赋值,并获得项目选项值itemID法一://项目列表ViewData["ItemID"]=string.IsNullOrEmpty(itemID)?"4":itemID;varResult=fromaindb.Fee_It......
  • Java 中 List 分片的 5 种方法!
    这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战前些天在实现MyBatis批量插入时遇到了一个问题,当批量插入的数据量比较大时,会导致程序执行报错,如下图所......
  • Java 做项目能用到 List 的场景,这篇总结全了
    本文为掘金社区首发签约文章,14天内禁止转载,14天后未获授权禁止转载,侵权必究!List代表有顺序的一组元素,顺序代表遍历元素时是有顺序的,先放进List的元素会先被遍历到,这......
  • Listener
    Listener监听器什么是Listener监听器?监听器是Servlet规范中的一员为什么要有监听器?监听器实质上是Servlet规范留给web程序的特殊时机如果特殊时段想使用某段代......
  • C# DataTable和List之间相互转换
    ​ 目录前言想法两者的区别个人想法完整代码方式一方式二类型转换 前言最近在捣鼓DataTable,弄到了类型转换,既然弄了,那就整个记录。有不足之处,请多多指教。......
  • MySQL Data source rejected establishment of connection, message from server: “T
    MySQL数据库中Datasourcerejectedestablishmentofconnection "Toomanyconnections"异常解决错误原因: 利用C3P0数据源,连接MySQL服务器时,产生了太多的连接数,数据库客......
  • 记录:去除list<Map<String,Object>>中主键重复的map
    /**mapKey 主键key**/publicstaticList<Map<String,Object>>removeRepeatMapByKey(List<Map<String,Object>>list,StringmapKey){List<Map<String,Object>......