(LIS longest increasing subsequence) given a sequence, delete any number of the remainder of the sequence is called a sub-sequence of it, to find its longest sub-sequence, satisfies the elements in the subsequence is monotonically increasing.
For example, given the sequence {1,6,3,5,4}, the answer is 3 because {1,3,4} and {1,3,5} are the two Kanako sequences with the longest length.
Where to look at this question, how to do? A universal enumeration? Enumerate all 2^n subsequence, find the longest, certainly can, is too high complexity. Why should we enumerate them? Because you want to know what number to take, in fact, we just need to consider the last number and take a few numbers on it? Because monocytogenes means bigger than the previous one, we have to add this number, only to consider that it is larger than the last number added. And the longest meaning is the number of the most, we just know the number of the total number can be, there is no need to know the specific number.
Let's try a way of thinking with dynamic planning. First set the series is A1, A2, A3...an, in order to facilitate us to join a a0=-∞, we will find that this will bring us great convenience. int F[i] Represents the length of the longest monotone subsequence ending with number I, so let's look at the last number before joining AI is AJ, obviously J < I and AJ < AI, we have f (i) = f (j) + 1, because there is an extension to the back. According to this equation, we should obviously choose the largest F (j) to make F (i) the largest.
So we have a recursive relationship f (i) = Max{f (j) | J < I and AJ < AI} + 1, the light has a recursive relationship is not enough, the initial value? F (0) = 0, and we join the a0=-∞, so for each i > 0,j always exist, the big deal to reach the subscript 0.
Pseudo Code:
f[00; for 1 Do 0; for 0 1 Do 1) endforendfor
Obviously the time complexity of this algorithm is O (n^2), and the spatial complexity is O (n). Cliché question, how to find such a longest sub-sequence? It's always possible to record decisions. Let's record what makes F (i) the largest J. The end result is max{f (i)}, we can find the previous J from this I-value an item continuously ...a better algorithm?
In fact, this problem sometimes has a lower complexity algorithm. Still with {1,6,3,5,4} as an example, we imagined that when considering 5, there were two subsequence {1,6} and {1,3} of length 2, which would be better? Obviously the latter is better, since 3:6 is small, and the sequence ending with 3 is more likely to be followed by a number in the back. Then we record the size of the last number of the "best" of the monotone subsequence of each length before the number I, considering where to put the current number. In fact, what we mean is to select a representative in the monotone sequence of each length, which is the "best" one (to make the last one as small as possible), and we can conclude that the last item of the "best" monotone subsequence of different lengths is monotonically increasing with length. This is because every time we try to add a number to the longest sub-sequence it can pick up, it is added to the largest subsequence that it can add to the end.
so the question is clear, at first we only have a monotone subsequence of length 0, the end size is considered-∞. Assuming that we currently have a record of f[0],f[1],f[2]...f[m] indicating that the longest length of the current monotone subsequence is M, we consider where AI is receiving, we want to find the largest one that is smaller than the AI, and we take it back to that sequence. Because F is monotonically incrementing, in other words, we find x= max{x|f[x] < AI}, get the AI to f[x] behind, got f[x + 1] = AI, note that such x must exist, because f[0] =-∞. If we find the X < m, then we actually update the last item of the subsequence of length (x + 1), because obviously there is f[x + 1] >= ai, we change the AI over, at least not worse, which also formally we preserve the original intention of each length of the "best" monotone sub-sequence. if x = = m, we actually extend the length of the sequence (the number of species) to (M + 1).
What is the end result? Is the length of the F-list, which is the M-value after the final change.
If we look at the loop one by one, there is the time complexity of O (M), but because of the monotonicity, we can find this x using the binary lookup algorithm, so the time complexity here is O (LOGM), because M<=n, We can assume that the time complexity of finding x every time is O (Logn), so the time complexity of doing this for each AI is O (nlogn).
we got a faster algorithm. Consider how to find a specific subsequence? (Hint: It's still a "record" decision, and it's OK to record it when X is found.) )The following:
#include <cstdio>#include<cstring>using namespacestd;intn,a[1000001],f[1000001],MAXN;intMain () {memset (F,-127,sizeof(f)); scanf ("%d",&N); for(intI=1; i<=n;i++) scanf ("%d",&A[i]); for(intI=1; i<=n;i++) { if(A[I]>F[MAXN]) f[++maxn]=A[i]; Else if(a[i]<F[MAXN]) { intL=1, r=MAXN; while(l<=r) {intM= (L+R)/2; if(A[i]<f[m]) r=m-1; Else if(A[i]==f[m]) Break; Elsel=m+1; } if(F[l]>a[i]) f[l]=A[i]; }} printf ("%d", MAXN);}
If it helps you, do not forget to add praise Oh, the clatter!! See you next time! the
Basic explanation of dynamic regulation seven--the longest Kanako sequence