优化 最长上升子序列_最长上升子序列nlogn算法

以前搞算法的时候看到过这个算法,但是没有仔细钻研过,似懂非懂,这两天看了看,总算是搞明白了。

问题的背景我就不多说了,相信通过搜索引擎来到这里的都是为了寻求简单易懂的nlogn的答案。

这个算法dp的状态有点诡异:

dp[i] = 长度为i+1的上升子序列中末尾元素的最小值(没有某个长度的上升自序列的话相应位置是无穷大)

初看有点不太明白,为什么是末尾的最小值呢?为什么可以求出最长的公共子序列呢?为什么可以到nlogn呢?别急,我慢慢说。

首先,当这个算法执行完毕的时候,dp数组中的每一个都符合我们定义的状态,每个长度的上升子序列末尾最小值都有了。那么我们看看含有末尾最小值的最大的位置是什么就能找到问题的解了。

其次,我们怎么去进行状态的推算和更新?其实,这个算法已经是优化过的算法,搞的人都不清楚他要干啥了。这个算法的原始版本其实还有一维(详见PSS),如果我们知道N个元素组成的dp数组,那么如果这时候又来了一个元素怎么办?dp数组能很快更新么?必须是可以的。只要新来的元素比dp数组中的某个位置j上的元素大就可以了,那么新来的元素就可以更新dp[j]了,具体是if(dp[j-1]

for( int i = 0; i < n; i++ ){// index for arrays

for( int j = 0; j < n; j++ )// index for dp

if( j == 0 || (dp[j-1] < a[i] && a[i] < dp[j] ) )

dp[j]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值