求序列最长不下降子序列_动态规划浅析——最长不下降子序列和最长上升子序列问题...

本文聚焦动态规划中的最长不下降子序列和最长上升子序列问题。介绍了最长不下降子序列的定义,给出 \(O(n^2)\) 的搜索方法,分析状态、状态转移及初始条件,推导状态转移方程并进行复杂度分析。最长上升子序列解法类似,仅状态转移方程符号不同。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题简析

哈喽,动态规划问题的解析又来了!这次带来的是最长不下降子序列和最长上升子序列问题,因为这两个问题在代码上是99%以上的相似(仅有一个符号不同),所以把它们放在一起讲。那么什么叫最长不下降子序列?

假设序列

,我们要找一个最长不下降子序列,什么意思呢?就是设序列

。我们看这个序列,可以直观看出一个最长的不下降子序列为:

。如果我们直接用暴力搜索的方法,时间复杂度是

,只要序列再长一点,就已经是不可接受的时间了。

那么我们现在来讲一种

的搜索方法,至于

的方法,留待下一次讲吧~

最长不下降子序列问题

我们先来想一下,最长不下降子序列是一种什么样的问题?

它是一种有状态的问题,一个更长的不下降子序列,必定由一个较短的不下降子序列拼接而来。这样说不太严谨,我们来点数学定义:

若:

是一个不下降子序列,并且有

,那么

也是一个不下降子序列。这里的

是序列

中的任意一项(也即

),且序列

是一个不下降的序列。

我们可以从上述定义中看出,状态就是移动到第

个数,状态转移就是选择序列第

个数与否来构建新子序列。状态的初始条件就是把第

个数作为子序列的开头。

啊啊啊啊啊啊!怎么这么抽象!你是学数学的吗?

抱歉,并不是,接下来我们还是构建一个

序列,来看看子序列是怎么被找到的。

还是假设序列

,我们构建一个等长的

序列,

的意义是:在选择第

个状态与否的时候子序列最长的长度。

好,我们先来初始化

序列,因为序列

中的每个数单独拎出来做成一个序列,都是一个不下降子序列,比如

,

等等,它们都是序列

不下降的子序列。所以

的初始化条件为:

其中

是序列

的长度,在这里是6。

接下来我们开始遍历

序列,

,因为选择第0个元素构成的子序列

是当前的最长不下降子序列。

那么

是多少呢?我们首先得看

可以跟谁组成最长不下降子序列,我们发现

(并且也只有

可以选了),说明我们可以把6拼到

的后面,组成当前的最长不下降子序列

,这个时候,

接下来我们看

,和上面相同地,我们观察所有满足

,发现这个时候

。那么我们回想,

的含义是

状态下的不下降子序列的长度,因为我们要求的是子序列长度最长,所以有多个

满足的情况下,我们当然选

,这里的

代表取多个数中的最大值。我们发现

。所以也就是说延续1状态把

接上去,会得到最长的序列。

什么意思呢,如果采用

,得到的不下降子序列就是

。如果采用

,得到的不下降子序列就是

,那肯定是继承

的状态要优于

。那么这个时候

接下来我们看

,我们知道,首先得满足

,然后才能继续谈其他的。我们发现这个时候只有唯一解,那就是

。但是这个时候的

,那还不如直接不选

的情况,保留

这个子序列,也比选

所构造的

这个子序列长。

那后续就好办了,

,此时子序列为

,此时子序列为

。此时已经到最后一个序列元素了,状态转移也就停止了。

那么上面分析了那么多,如何得到状态转移方程呢?我们归纳一下,就是:

就是说,要么我不选第

个元素,维持上一个状态的不下降子序列。要么我去翻前面的可以构成不下降子序列的序列末尾元素(

),然后把

加到这个不下降子序列里,构成更长的不下降子序列。选哪种?当然是哪种可以让我的不下降子序列更长我选哪种。

比如我们上面分析

的时候,选不选

?选了,就只能构成

这个子序列。不选,还可以保留上个状态构成的

子序列。那明显不选更长,所以

函数就是这样使用的。

复杂度分析

遍历一遍

序列时间复杂度为

,在每一次搜索

的时间复杂度为

。所以总的时间复杂度就是

。空间复杂度就是

数组的空间,空间复杂度为

最长上升子序列问题

解法同最长不下降子序列问题,只是状态转移方程为:

可以发现大于等于号变成了大于号,这就是最长上升子序列的定义。

具体实现的代码留作课后习题。

思考题:你可以进一步下降这个问题的时间复杂度吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值