最长XXX子序列(什么都好啦)
相信很多小伙伴一般都会在DP里见到他们—>最长XXX子序列 的身影(垃圾玩意儿)原来我也一直不想要去了解这个东西,但是我还是(迫不得已)鼓起勇气去了解了一下这个东西,今天我们的主题就围绕着导弹拦截来展开讲述吧。(其实不管是什么序列,到时候改符号就差不多了)
首先,这些题题一般就是求一个最长XXX子序列的长度,而导弹拦截呢,就刚好是求长度的一个好问题(我才不是精心挑选的)所以.....
第一个小问,就是求最长不上升子序列长度,而对于第二个小问题,很多人可能没看明白,其实就是求最长上升子序列的长度,为什么呢?首先,我们假设最少有K个那什么玩意儿才能拦截所有导弹,然后对于第i个系统的任意一个高度,第i+1个系统里肯定有比它高的高度(不然你第i个系统早就把没它高的那玩意儿连上了啊),然后后面的同理,一直这样下去就行了..........
O(N^2)求长度
这个最暴力的方法,就是我们外层循环枚举一个子序列的结尾,然后内层从1到i-1,枚举这个子序列的倒数第二个,如果接的上,就取最优值,不然.......就啥也不干。
1 #include <bits/stdc++.h> 2 int a[100010]; 3 int num[100010]; 4 int dp[100010]; 5 int n=0; 6 int x; 7 int ans=0,maxn=0; 8 using namespace std; 9 int main() 10 { 11 while(cin>>x) 12 num[++n]=x; 13 for(int i=1;i<=n;i++)//因为开始每一个的序列长度都是自己 14 a[i]=dp[i]=1; 15 16 for(int i=1;i<=n;i++) 17 { 18 for(int j=1;j<i;j++)//枚举结尾和它前面的玩意儿 19 { 20 if(num[i]<=num[j]) 21 a[i]=max(a[i],a[j]+1);//替换 22 if(num[i]>num[j]) 23 dp[i]=max(dp[i],dp[j]+1); 24 } 25 } 26 27 for(int i=1;i<=n;i++)//求最长长度 28 { 29 ans=max(ans,a[i]); 30 maxn=max(maxn,dp[i]); 31 } 32 33 cout<<ans<<endl; 34 cout<<maxn; 35 return 0; 36 }
嗯,交上去就TLE了,看看N,绝对要炸啊,所以,聪明的大佬们果然又........
O(nlogn)求长度
我们开一个数组dp,然后从a数组(存导弹高度的)1遍历到n
遇到比dp数组最后一个小的,就接上去
dp[++len]=a[i]
不然,就只能高铁霸座了,找到第一个小于a[i],的数,直接占位子。但是问题来了,我们怎么找这个数,一般的人都会用而分,但是,像我这种聪明人就选择用STL里面自带的函数啦
lower_bound & upper_bound
假设查找x,
lower_bound是找出一个序列中第一个大于等于x的数
upper_bound是找出一个序列中第一个大于x的数(亲兄弟啊)
然而平常这俩玩意儿都是针对升序的(那还有什么用啊)
但是根据编C++的人的尿性,肯定会有自定义函数的啊,没错,所以.....
lower_bound(dp+1,dp+1+n,x,cmp);
是不是和sort很像,只需要自己打一个比较函数就可以了(但是我懒,所以.....)
lower_bound(dp+1,dp+1+n,x,greater<int>());
和上面差不多,专为懒人设计你值得拥有
但你要知道,它返回的却是个指针(指针什么的最烦了)
所以,你用指针的话.......
int *p = lower_bound(自己想象);
或者直接减去数组开头指针,差就是下标
int p=lower_bound(自己想象)-a;
然后要注意,dp里存的并不是最大不上升子序列,因为它每时每刻(简单快乐)都在更新嗯,就这样,让我们来愉快的模拟样例吧
a={0,389,207,155,300,299,170,158,65} a[i]=389 dp={0,389} len=1 dp[len=389]第一个直接进去
a={0,389,207,155,300,299,170,158,65} a[i]=207 dp={0,389,207} len=2 dp[len]=207然后,下一个比这一个小,加进去
a={0,389,207,155,300,299,170,158,65} a[i]=155 dp={0,389,207,155} len=3 dp[len]=155继续加
a={0,389,207,155,300,299,170,158,65} a[i]=300 dp={0,389,300,155} len=3 dp[len]=155哦吼,比这个大了,我们只能踢人了
a={0,389,207,155,300,299,170,158,65} a[i]=299 dp={0,389,300,299} len=3 dp[len]=299继续踢人
a={0,389,207,155,300,299,170,158,65} a[i]=170 dp={0,389,300,299,170} len=4 dp[len]=170加进去
a={0,389,207,155,300,299,170,158,65} a[i]=158 dp={0,389,300,299,170,158} len=5 dp[len]=158加进去
a={0,389,207,155,300,299,170,158,65} a[i]=65 dp={0,389,300,299,170,158,65} len=6 dp[len]=65加进去
好啦,模拟完了(好水啊)
最后贡献一下我的代码吧
1 #include<bits/stdc++.h> 2 using namespace std; 3 int len1=1,len2=1; 4 int a[100005]; 5 int d1[100005],d2[100005]; 6 int n; 7 int main() 8 { 9 while(cin>>a[++n]); 10 n--; 11 d1[1]=a[1]; 12 d2[1]=a[1]; 13 for(int i=2;i<=n;i++) 14 { 15 //最长不上升子序列长度 16 if(a[i]<=d1[len1]) 17 d1[++len1]=a[i];//加进去 18 else *upper_bound(d1+1,d1+1+len1,a[i],greater<int>())=a[i];//踢人 19 //最长上升子序列的长度 20 if(a[i]>d2[len2]) 21 d2[++len2]=a[i]; 22 else *lower_bound(d2+1,d2+1+len2,a[i])=a[i]; 23 } 24 cout<<len1<<endl<<len2; //输出就好 25 return 0; 26 }
转载于:https://www.cnblogs.com/hualian/p/11266155.html
最长XXX子序列(什么都好啦)相关推荐
- 都能看懂的LIS(最长上升子序列)问题
LIS问题介绍: 首先来说一下什么是LIS问题: 有一个长为n的数列a0, a1, ......, a(n-1).请求出这个序列中最长的上升子序列的长度.上升子序列指的是对于任意的i<j都满足a ...
- 最长公共子序列、最长连续公共子序列、最长递增子序列
面试中除了排序问题,还会经常出现字符串的子序列问题,这里讲解使用动态规划解决三个常见的子序列问题: 1.最长公共子序列问题(LCS,longest-common-subsequence problem ...
- 算法复习——动态规划篇之最长公共子序列问题
算法复习--动态规划篇之最长公共子序列问题 以下内容主要参考中国大学MOOC<算法设计与分析>,墙裂推荐希望入门算法的童鞋学习! 1. 问题背景 子序列:将给定序列中零个或多个元素(如字符 ...
- 算法设计与分析——动态规划(五):最长公共子序列
分类目录:<算法设计与分析>总目录 相关文章: · 动态规划(一):基础知识 · 动态规划(二):钢条切割 · 动态规划(三):矩阵链乘法 · 动态规划(四):动态规划详解 · 动态规划( ...
- 最长公共子序列(LCS)问题 Longest Common Subsequence 与最长公告字串 longest common substr...
问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X="x0,x1,-,xm-1",序列Y=& ...
- leetcode-300 最长上升子序列
题目描述: 给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度 ...
- java实现最长连续子序列_最长公共子序列 ||
问题:在 前一篇文章 最长公共子序列 | 的基础上要求将所有的最长公共子序列打印出来,因为最长公共子序列可能不只一种. 难点:输出一个最长公共子序列并不难,难点在于输出所有的最长公共子序列,我们需要在 ...
- 动态规划——最长上升子序列问题 两种角度及优化算法
最长上升子序列 OpenJ_Bailian - 2757 一个数的序列 bi,当 b1 < b2 < ... < bS的时候,我们称这个序列是上升的.对于给定的一个序列( a1, a ...
- 触类旁通,经典面试题最长公共子序列应该这么答
作者 | labuladong 来源 | labuladong(ID:labuladong) [导读]最长公共子序列(Longest Common Subsequence,简称 LCS)是一道非常经 ...
最新文章
- 6. Oracle闪回特性
- SpringBoot在IDEA中实现热部署
- <X86汇编语言:实模式到保护模式>四十六 中断和异常的处理与抢占式多任务
- 在二分类问题中,准确率一直处于50%上下的解决方法
- MySQL存储过程相互调用
- 《精通正则表达式》笔记 --- 选择引号内的文字
- 功放(耳机/音箱)声压级计算(五)
- selenium元素定位——下拉选择框
- yoga710怎么进入bios_重装系统看不懂bios?超详细中英文翻译,教你1分钟识别bios各项...
- 字幕文件srt格式解析
- 用EndNote引用文献出现‘参数错误’解决方式
- goodnote笔记同步 Android,goodnotes笔记
- 机器人学导论(一)——空间描述和变换
- 史上最暖2月谁制造?
- Android开发框架汇总
- oracle查询语句中select from where group by having order by的解释与应用
- JavaSE基础语法中的修饰符
- 李开复:大学四年应是这样度过
- c语言123l表示什么,C语言的基本数据类型及其表示
- 托福百日冲刺—词汇(11)
热门文章
- @entity 不限字节长度的类型_面试常考,项目易错,长文详解C/C++中的字节对齐...
- C++设计模式(全网最通俗易懂的设计模式进阶)
- python 人工智能课程对孩子的好处_少儿编程有什么好处?儿童编程课程学习Python的4大原因...
- linux sys伪用户作用,linux用户管理详解
- 处理增删改_实现数据的增删改查
- 白鹭引擎生成html,初识Egret白鹭引擎 之 创建舞台
- php简介的编辑器,推荐几款功能强大的PHP编辑器
- apt apt 用法_apt命令–实用用法指南
- 具有IDE或IDE插件的Spring Boot Initilizr
- 主流Java微服务框架有哪些?-开课吧