Looking back on WOJ1398 today, we found this algorithm that was not understood at the time.
For a long time, now I finally want to understand.
Try to write it down and let yourself know better.
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 d[5], 9 update to d[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)!
The code is as follows:
1#include <iostream>2#include <stdio.h>3#include <alloca.h>4 using namespacestd;5 //Arr[s in non-descending sequence: E] (closed interval) on the second find the first position greater than or equal to key, if both are less than key, return e+16 intUpper_bound (intArr[],intSintEintkey)7 {8 intmid;9 if(Arr[e] <=key)Ten returnE +1; One while(S <e) A { -MID = S + (e-s)/2; - if(Arr[mid] <=key) thes = mid +1; - Else -E =mid; - } +cout<<"**"<<s<<Endl; - returns; + } A at intLIS (intD[],intN) - { - inti =0, Len =1, *end = (int*) Alloca (sizeof(int) * (n +1)); -end[1] = d[0];//initialization: 1 of the LIS End is d[0] - for(i =1; I < n; i++) - { in intpos = Upper_bound (end,1, Len, D[i]);//Find insertion Position -End[pos] =D[i]; to if(Len < POS)//update lis lengths as needed +Len =Pos; - } the returnLen; * } $ Panax Notoginseng intMain () { - //int a[] = {5, 3, 4, 8, 6, 7}; the intA[] = {2,1,5,3,6,4,8,9,7}; +Cout<<lis (A,9) <<Endl; A}
See original posts
DP (Dynamic Programming) LIS (longest increasing subsequence) problem (RPM)