[Transfer] http://skynewborn.blog.sohu.com/66594610.html
Monotonic subsequences include monotonically incrementing subsequences and descending subsequences without losing their universality. Here we only discuss monotonic incrementing subsequences. First, let's clarify our problems from the definition. Given sequences A1, A2 ,..., An. If there is a subsequence that meets the following conditions
AI1 <= ai2 <=... <= Aim, (I1 <I2 <... <IM)
It is called a monotonic increasing subsequence whose original sequence length is M. Now the problem is that we need to find the longest monotonic increasing subsequence of a sequence.
Intuitively, a sequence Sn contains 2n subsequences, which enumerate all subsequences, locate the monotonically incrementing sequence, and return the longest of them, in this way, our problem is solved. Of course, this intuitiveAlgorithmThe time is O (2N * n), and its complexity increases too fast. Therefore, we should do better.
So let's look at it from another angle. Suppose we sort (increment) The Sn and get the sn '. Then, the longest common sub-sequence cm of Sn and Sn is the longest monotonic increasing sub-sequence we require (if you do not know the definition of the longest common sub-sequence, just Google it ). Why? Assume that cm' is the longest monotonous subcolumn of Sn, and cm '! The length of = cm, CM 'is greater than cm. Because cm 'is incremental and every element of CM' comes from SN, CM 'must be a child column of Sn, and CM' is a child column of Sn, therefore, CM is the common sub-column of Sn and Sn, so the length of CM must be smaller than cm, which is in conflict with assumptions. Therefore, CM is the longest monotonous sub-column. Theoretically, ourAlgorithmCorrect. In terms of complexity, dynamic programming (Dynamic Programming) is used to solve LCS (longest public subcolumn, longest-common-subsequence). The time is O (n2 ), the space is also O (n2 ). Therefore, you need to sort the SnNlognWhile LCS requires N2. Finally, ourAlgorithmThe time is O (n2 ).
We can see that through the above improvement, ourAlgorithmThe efficiency has been greatly improved (from exponential growth to polynomial growth ). However, the pleasure of programming is that it will constantly surprise us, so it is better to stop what we should do.AlgorithmIt should exist.
For sequence Sn, consider the monotonic subcolumns whose length is I (1 <= I <= m). Such subcolumns may have multiple. We select the minimum value of the ending element of these child columns (the last element of the Child column. In Li format. Yi Zhi
L1 <= L2 <=... <= LM
If li> LJ (I <j), remove the last J-I element of the incremental subsequence ending with LJ to obtain a subsequence with the length of I, the accesskey <= LJ <li at the end of the sequence, which is in conflict with the minimum end element of the incremental subsequence identified by Li. Therefore, the above conclusion is proved. Now, let's look for the L sequence corresponding to the SN. If we find the largest Li is Lm, then M is the length of the largest monotonic subcolumn. The following method can be used to maintain L.
Scans the SN from left to right. For each AI, it may
(1) AI <L1, then L1 = ai
(2) If AI> = LM, then lm + 1 = ai, M = m + 1 (m is the largest l subscript currently seen)
(3) ls <= AI <ls + 1, then LS + 1 = ai
After scanning, we will getLongest ascending subsequence. From the above method, we can see that for each element, we need to perform the search operation on L. Because l is ordered, this operation is logn, so the total complexity is O (Nlogn). Better than start O (n2)Algorithm. Here is my implementation :(AlgorithmNo specific sequence is returned, but the return length)
1 template <typename T>
2 int LMS (const T * data, int size)
3 ...{
4 if (size <= 0)
5 return 0;
6
7 T * S = new T[size];
8 int S_Count = 1;
9 S[0] = data[0];
10
11 for (int i = 1; i < size; i++)
12 ...{
13 const T & e = data[i];
14 int low = 0, high = S_Count - 1;
15
16 while (low <= high)
17 ...{
18 int mid = (low + high) / 2;
19
20 if (S[mid] == e)
21 break;
22 else if (S[mid] > e)
23 ...{
24 high = mid - 1;
25 }
26 else
27 ...{
28 low = mid + 1;
29 }
30 }
31
32 //well, in this point
33 //high is -1, indicating e is the smallest element.
34 //otherwise, high indicates index of the largest element that is smaller than e
35 if (high == S_Count - 1)
36 S[S_Count++] = e;
37 else
38 S[high + 1] = e;
39 }
40
41 return S_Count;
42 }
The longest monotonic subsequence and Its counting problem
Http://hi.baidu.com/vincentz/blog/item/6df5a3c2be3ffa180ef477e2.html