
AcWing 896. 最长上升子序列 II 【贪心+二分】
发布日期:2021-05-07 08:50:09
浏览次数:22
分类:原创文章
本文共 1143 字,大约阅读时间需要 3 分钟。
hello大家好,欢迎大家访问 林深时不见鹿 的博客,算法小白,记录学习的点滴日常,致力于通俗易懂的题解,相遇即是上上签,如有不足,还请多多指教。
目录
1.题目
给定一个长度为N的数列,求数值严格单调递增的子序列的长度最长是多少。
输入格式
第一行包含整数N。
第二行包含N个整数,表示完整序列。
输出格式
输出一个整数,表示最大长度。
数据范围
1≤N≤100000,
−109≤数列中的数≤109
输入样例:
7
3 1 2 1 8 5 6
输出样例:
4
2.思路 (贪心+二分) O(nlogn)
朴素版的LIS时间复杂度为O(n^2)会超时,因此这道题我们用贪心+二分来做。
先讲贪心思路:
我们定义一个数组q[],让q数组来存贮同一长度下的上升子序列结尾的最小值。因为如果我们可以接到一个更大的数后面,那么我们一定可以接到一个更小的数后面, 接到更小的数后面可以为我们留出更大的空间来接其他的数,使得数组的长度更长。可以证明q数组一定是单调上升的 最后q数组的长度就是答案 。
再讲二分:
如何更新q数组呢?
我们遍历原来的a数组,对于每个a[i],我们在q[]数组查找小于a[i]的最大的数x。找到以后我们将x的后一个数更新成a[i],因为x是小于a[i]的最大的数,那么x的后一个数一定是大于等于a[i]的。这个也好证明,如果x的后一个数也小于a[i],那么q数组中小于a[i]的的最大的数就不是x了而是x的后一个数了(数组q单调上升),这与我们二分的结果相反。
3.代码
#include<iostream>#include<cstdio>#include<algorithm>using namespace std;const int N=1e5+10;int a[N];int q[N];int main(){ int n; scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&a[i]); int len=0; for(int i=0;i<n;i++) { int l=0,r=len; while(l<r) //二分去更新数组q { int mid=l+r+1>>1; if(q[mid]<a[i]) l=mid; else r=mid-1; } q[r+1]=a[i]; len=max(len,r+1); } printf("%d\n",len); return 0;}
发表评论
最新留言
很好
[***.229.124.182]2025年04月15日 04时50分25秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Hibernate入门(四)---------一级缓存
2021-05-09
MySQL事务(学习笔记)
2021-05-09
一个web前端开发者的日常唠叨
2021-05-09
内存分配-slab分配器
2021-05-09
技术写作技巧分享:我是如何从写作小白成长为多平台优秀作者的?
2021-05-09
Jupyter Notebook 暗色自定义主题
2021-05-09
[Python学习笔记]组织文件
2021-05-09
基于Redo Log和Undo Log的MySQL崩溃恢复流程
2021-05-09
从RocketMQ的Broker源码层面验证一下这两个点
2021-05-09
如何正确的在项目中接入微信JS-SDK
2021-05-09
纵览全局的框框——智慧搜索
2021-05-09
快服务流量之争:如何在快服务中占领一席之地
2021-05-09
【活动】直播揭秘<如何从0开发HarmonyOS硬件>
2021-05-09
Unity平台 | 快速集成华为性能管理服务
2021-05-09
详细实例教程!集成华为虚假用户检测,防范虚假恶意流量
2021-05-09
对模拟器虚假设备识别能力提升15%!每日清理大师App集成系统完整性检测
2021-05-09
使用Power BI构建数据仓库与BI方案
2021-05-09
pytest封神之路第二步 132个命令行参数用法
2021-05-09
Django认证系统并不鸡肋反而很重要
2021-05-09
快用Django REST framework写写API吧
2021-05-09