(在研读大佬写的博客后,打算记录下自己学习过程)
通过最长上升子序列的拓展了解到,其实这是一个系列的问题主要代表有:
1 最长上升子序列
2 最长不上升子序列
3 最长下降子序列
4 最长不下降子序列
就以最长上升子序列为例。(注意:这里面说的子序列不连续的)
得到一个数组,求这个数组的最长上升子序列长度
3 1 2 1 8 5 6
可以直接看出来这个数组的最长上升子序列是1 2 5 6,其长度也就是4.一眼就能看出来,但是用代码该怎么实现呢?
介绍俩种方法:
dp思想
只能用于数据小的情况,要不然会TLE
目前为止所接触的dp思想核心就在状态转移方程上。同时也用到了贪心的思想。在所有的上升序列中最开始的长度都是1(算上它自身)。那么这个时候就只要考虑以arr[i]结尾的子序列中使其最长即可。找到arr[i]然后在从头开始枚举,只要满足arr[j]
brr[1]=1 (本身长度为1)
brr[2]=1;
brr[3]=2;
brr[4]=1;
brr[5]=3;
.......以此类推
#include
#include
#include
#include
#include
#include
#include
//#include
#include
二分思想
用于处理大型数据
先来看例子
3 1 2 1 8 5 6
1、如图所示,可以发现找到长度为1的上升子序列,若后面的数能接到3的后面,那么一定能接到1的后面,因为1比3更好,扩展度高
2、使用q[]存储所有不同长度的上升子序列结尾的最小值
3、进来一个数arr[i]时,通过二分在q[]中找到最大的小于arri的数,就能够将arri接到该数的后面,即更新q[r + 1] = arr[i]
#include
#include
#include
#include
#include
#include
#include
//#include
#include
浅浅举个例子
拦截导弹
某国为了防御敌国的导弹袭击,开发出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭,并观测到导弹依次飞来的高度,请计算这套系统最多能拦截多少导弹。拦截来袭导弹时,必须按来袭导弹袭击的时间顺序,不允许先拦截后面的导弹,再拦截前面的导弹。
Input
输入有两行,
第一行,输入雷达捕捉到的敌国导弹的数量k(k<=25),
第二行,输入k个正整数,表示k枚导弹的高度,按来袭导弹的袭击时间顺序给出,以空格分隔。
Output
输出只有一行,包含一个整数,表示最多能拦截多少枚导弹。
Sample
Inputcopy | Outputcopy |
---|
8
300 207 155 300 299 170 158 65
| 6 |
注意细节:后一发的导弹高度不能高于前一段也就是严格小于,所以就是求最大下降子序列
#include
#include
#include
#include
#include
#include
#include
//#include
#include