Algorithm of the longest non descending subsequence (LIS)
I messed with the data
input 10 1 3 7 3 6 1 3 2 4 5 output 6
Obviously, the longest subsequence of the above data is {1,3,3,3,4,5}, and the length is six.
1, Violent dp
Easy to think of:
For a sequence A[1..n], f[i] represents the longest subsequence from Ai to An,
Then the transfer equation is: f[i]:=max(f[i],f[j+1]) [i:=n downto 1;j:=i+1 to n;f[i] is initially 1]
Time complexity O(n^2)
Code:
var n,i,j,max:longint;
a,f:array[1..10000]of longint;
function max1(a,b:longint):longint;
begin
if a>b then exit(a)
else exit(b);
end;
begin
readln(n);
for i:=1 to n do
read(a[i]);
for i:=n downto 1 do
begin
f[i]:=1;
for j:=i+1 to n do
if a[j]>=a[i] then
f[i]:=max1(f[j]+1,f[i]);
end;
for i:=1 to n do
if f[i]>max then max:=f[i];
writeln(max);
end.
Obviously, when the data is more than 10000, it will be T.
2, Binary optimization of monotone queue
Make an array B[1..lenb]
b[i] represents the last element in the longest subsequence from 1 to I
It can be found that B is monotonous
Every time we read in an Ai, we only need to maintain B monotony
Maintenance uses binary search to find that b[i] satisfies b[i-1 < = x < b[i + 1], with complexity O(log n)
Finally, output lenb
Total complexity O(n log n)
Code:
var n,i,x,l,r,w,mid:longint;
a:array[0..1000000]of longint;
begin
readln(n);
for i:=1 to n do
begin
read(x);
if x>=a[w] then
begin
inc(w);a[w]:=x;
end
else
begin
l:=1;r:=w;
while l<r do
begin
mid:=(l+r) div 2;
if a[mid]<=x then l:=mid+1
else r:=mid;
end;
a[r]:=x;
end;
end;
writeln(w);
end.
Thank you!