动态规划之最长子序列问题

一个数的序列bi,当b1 < b2 < … < bS的时候,我们称这个序列是上升的。
对于给定的一个序列(a1, a2, …, aN),我们可以得到一些上升的子序列(ai1, ai2, …, aiK),这里1 <= i1 < i2 < … < iK <= N。
比如,对于序列(1, 7, 3, 5, 9, 4, 8),有它的一些上升子序列,如(1, 7), (3, 4, 8)等等。这些子序列中最长的长度是4,比如子序列(1, 3, 5, 8).
我们的任务,就是对于给定的序列,求出最长上升子序列的长度。(最长不上升子序列就是正相反呗。)

下面我们以最长上升子序列为例研究。
其他非递增(减)等一系列问题就是以此为基础啊,比较的时候改改条件就行啊!
看清题目要求!
递增和不下降是不一样的啊摔!

O(n²)算法

seq[i]表示输入的第i个元素,seqlen[i]表示以第i个元素为末位的最长子序列长度。
在seqlen数组里选出最长,就是最长子序列长度啊。

O(nlogn)算法

arr[i]表示输入的数组元素,ans[len]表示生成长度为len时子序列的末位元素,len表示序列长度。
如果arr数组的新元素比ans数组的所有元素都大,把这个元素放在ans数组的最后,子序列长度+1;
如果arr数组的新元素比ans数组的最大元素小,比ans数组的其他元素小,那就用新元素替换掉这个最大元素。比如len=2时,ans[2]={1,5};若ans[i]即新元素为3,那就替换掉5,使得ans[2]={1,3},以保证有更多元素加入到序列中来。
所以我们发现,我们插入这个数据是通过替换来实现的,因而我们可以通过二分查找快速找到要替换的元素,从而将时间复杂度降低到O(nlogn)。

来举个栗子~
假设存在一个序列arr[1..9] = 2 1 5 3 6 4 8 9 7,可以看出来它的LIS长度为5。
下面一步一步试着找出它。
我们定义一个序列ans,然后令 i = 1 to 9 逐个考察这个序列。
此外,我们用一个变量Len来记录现在最长算到多少了
首先,把arr[1]有序地放到ans里,令ans[1] = 2,就是说当只有一个数字2的时候,长度为1的LIS的最小末尾是2。这时Len=1。

然后,把arr[2]有序地放到ans里,令ans[1] = 1,就是说长度为1的LIS的最小末尾是1,arr[1]=2已经没用了,这时Len=1。

接着,arr[3] = 5,arr[3]>ans[1],所以令ans[1+1]=ans[2]=arr[3]=5,就是说长度为2的LIS的最小末尾是5,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值