最长上升子序列(NlogN)

基于二分查找和队列优化的最长上升子序列求法:O(NlogN)高效算法
本文介绍了一种优化后的算法,通过结合二分查找和队列技术,将最长上升子序列问题的时间复杂度从O(n^2)优化到O(nlogn)。该算法采用动态规划的思想,使用f数组记录当前最长上升序列长度为i时的最小结尾元素,通过比较和查找,不断更新序列长度,实现高效的计算。
算法:基于二分查找和队列优化的最长上升子序列求法
 
分析:原方法是O(n2)的复杂度,下面来讲解一下O(NlogN)的算法。
      设一个f[i]表示当前最长上升序列长度为i时的最小值,我们希望以最小值进行更新,原因就是它能更新更多的值。

      若存在a[i]>f[ans],那么直接加入一位,并放入f[ans+1]这个位置;否则就进行查找,找到一个最靠前的位置使得a[i]<f[l]并进行替换,这样的话再次更新时又能更新更多的值。

program NlogN;



const

 maxn=5000;



var

 f,a:array [0..maxn] of longint;

 n,ans:longint;



procedure init;

var

 i:longint;

begin

 readln(n);

 for i:=1 to n do read(a[i]);

 f[1]:=a[1];

 ans:=1;

end;



procedure main;

var

 i,x,l,r,mid:longint;

begin

 for i:=2 to n do

  begin

   x:=a[i];

   if x>f[ans] then

    begin

     inc(ans);

     f[ans]:=x;

    end

   else

    begin

     l:=1;

     r:=ans;

     while l<r do

      begin

       mid:=(l+r) shr 1;

       if x>f[mid] then l:=mid+1 else r:=mid;

      end;

     if x<f[l] then f[l]:=x;

    end;

  end;

end;



begin



 init;

 main;

 writeln(ans);



end.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值