Typical variants of the longest ascending subsequence (LIS), the n^2 of the familiar is timed out. The LIS problem can be optimized for NLOGN algorithms.
Definition D[k]: The last element of the ascending subsequence of the length k , if there are multiple ascending sub-sequences with a length of K, the smallest of the last elements is recorded.
Note that the elements in D are monotonically increasing, and this property is used below.
First len = 1,d[1] = a[1], then to A[i]: if A[i]>d[len], then len++,d[len] = A[i];
Otherwise, we will find a J in d[1] to d[len-1], according to the definition of D, we need to update the last element of the ascending sub-sequence of length J (to make it the smallest), i.e. d[j] = A[i];
The final answer is Len.
Using the monotonicity of D, when looking for J, we can find two points, thus the time complexity is NLOGN.
==================================
Nlogn algorithm for longest ascending subsequence sequence
In the Sichuan OJ encountered a problem can not be used n^2 too, all kinds of entanglements, the last acquisition of NLOGN algorithm
The longest increment subsequence, longest increasing subsequence below we précis-writers for LIS.
The sort +lcs algorithm and the DP algorithm are ignored, both of which are too easy to understand.
Suppose there is a sequence d[1..9] = 2 1 5 3 6 4 8 9 7, it can be seen that the LIS length is 5.
Try to find it step by step below.
We define a sequence B and then let i = 1 to 9 examine the sequence one at a.
In addition, we use a variable len to record the maximum number of times now.
First, put d[1] in order B, make b[1] = 2, that is, when there are only 11 digits 2, the smallest end of the LIS with a length of 1 is 2. Then Len=1
Then, put d[2] in an orderly place in B, so that b[1] = 1, that is, the minimum length of the LIS is 1,d[1]=2 is useless, it is easy to understand it. Then Len=1
Next, d[3] = 5,d[3]>b[1], so make b[1+1]=b[2]=d[3]=5, that is, the minimum end of the LIS with a length of 2 is 5, it is easy to understand. This time b[1..2] = 1, 5,len=2
Again, d[4] = 3, it just add to 1, 5, placed in the position of 1 is obviously inappropriate, because 1 is less than 3, the minimum length of the LIS is 1, so it is easy to infer that the length of the LIS min 1 is 2, so you can eliminate 3, this time b[1..2] = 5, 3,len = 1
Continue, d[5] = 6, it is behind 3, because b[2] = 3, and 6 is behind 3, so it is easy to infer b[3] = 6, then b[1..3] = 1, 3, 6, or is it easy to understand? Len = 3, OH.
6th, D[6] = 4, you see it between 3 and 6, so we can replace 6, get b[3] = 4. B[1..3] = 1, 3, 4, Len continues to be equal to 3
7th one, d[7] = 8, it's big, bigger than 4, uh. So b[4] = 8. Len becomes 4.
8th, D[8] = 9, get b[5] = 9, uh. Len continues to grow, to 5.
The last one, d[9] = 7, which is between b[3] = 4 and b[4] = 8, so we know that the latest b[4] =7,b[1..5] = 1, 3, 4, 7, 9,len = 5.
So we know the length of the LIS is 5.
!!!!! Attention. This 1,3,4,7,9 is not the LIS, it just stores the corresponding length to the minimum end of the LIS . With this at the end, we can insert data one at a-one place. Although the last d[9] = 7 update is not meaningful for this set of data, but if there are two numbers 8 and 9, then you can update 8 to b[5], 9 update to b[6], the length of the LIS is 6.
Then you should find one thing: inserting data in B is ordered and is replaced without moving--that is, we can use a binary search to optimize the insertion time of each number to O (logn) ~~~~~ The time complexity of the algorithm is reduced to O (NLOGN)!
/*HDU 1950 Bridging signals-----Longest ascending subsequence Nlogn algorithm*/#include<cstdio>#include<cstring>#defineMAXN 40005intArr[maxn],ans[maxn],len;/*two-point lookup. Note that this binary lookup is for the nether; (What is the Nether?) For more details, see the "Getting Started with the algorithm" P145) returns the first position of the object that >= is looking for (think about why) can also be used to find the lower bound of the STL lowe_bound binary*/intBinary_search (inti) { intLeft,right,mid; Left=0, right=Len; while(left<Right ) {Mid= left+ (right-left)/2; if(Ans[mid]>=arr[i]) right=mid; ElseLeft=mid+1; } returnLeft ;}intMain () {Freopen ("Input.txt","R", stdin); intt,p,i,j,k; scanf ("%d",&T); while(t--) {scanf ("%d",&p); for(i=1; i<=p; ++i) scanf ("%d",&Arr[i]); ans[1] = arr[1]; Len=1; for(i=2; i<=p; ++i) { if(arr[i]>Ans[len]) ans[++len]=Arr[i]; Else{ intPos=binary_search (i);//if using Stl:pos=lower_bound (Ans,ans+len,arr[i])-ans;Ans[pos] =Arr[i]; } printf ("%d\n", Len); } return 0;}
O (NLOGN) algorithm for longest ascending subsequence (LIS) length