算法:基于二分查找和队列优化的最长上升子序列求法
分析:原方法是O(n2)的复杂度,下面来讲解一下O(NlogN)的算法。
设一个f[i]表示当前最长上升序列长度为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.