Storage extension algorithm n2 programming c writes a program with as low time complexity as possible, and calculates the length of the longest incrementing sub-sequence in a one-dimensional array (N elements.
For example, in sequence 1,-1,-3, 4,-5, 6,-7, the longest ascending subsequence is 1, 2, 4, 6, or-1, 2, 4, 6. (Beauty of programming P198-202)
Analysis and Solution
Based on the requirements of the question, find the longest incrementing sub-sequence in the one-dimensional array, that is, find a sequence of numbers B [0], B [1],…, B [m] (0 <= B [0] <B [1] <... <B [m] <N) so that array [B [0] <array [B [1] <... <Array [B [m].
Solution 1
Based on the definition of No-efficiency, we know that after the stages are arranged in a certain order, for a given stage status, the status of the previous stages cannot directly affect its future decision-making, but can only be indirectly affected through the current status. In other words, each status is a complete summary of history.
Similarly, we still take sequence 1,-1,-3, 4,-5, 6,-7 as an example. After finding 4, we do not care about the two values before 4, because it has no direct impact on finding 6. Therefore, this problem is ineffective and can be solved through dynamic planning.
You can analyze the target strings: 1,-1, 2,-3, 4,-5, 6,-7 by the number pattern.
Use I to represent the current traversal position
When I = 1, it is clear that the longest incremental sequence is (1) and the sequence length is 1.
When I = 2 is, because-1 <1. Therefore, you must discard the first value and recreate the string. The current incremental sequence is (-1) and the length is 1.
When I = 3, because 2> 1, 2>-1. Therefore, the longest incremental sequence is (1, 2), (-1, 2), and the length is 2. Here, whether the prefix 2 is 1 or-1 does not directly affect the incremental sequence after the result is obtained. (But it may be affected in other cases)
After such a push, we come to the following conclusion.
Assume that the maximum length of the ascending sub-sequence in the first I element of the target array [] is LIS [I]. So,
LIS [I + 1] = max {1, LIS [k] + 1}, array [I + 1]> array [k], for any k <= I
That is, if array [I + 1] is greater than array [k], then the I + 1 element can be connected to the Child sequence of LIS [k] to form a longer child sequence. At the same time, array [I + 1] can constitute at least a sub-sequence with a length of 1.
According to the above analysis, you can get the code list:
C ++ code:
Copy codeThe Code is as follows: int Max (int * a, int n)
{
Int max = a [0];
For (int I = 1; I <n; I ++)
If (max <a [I])
Max = a [I];
Return max;
}
Int LIS (vector <int> & array)
{
Int * a = new int [array. size ()];
For (int I = 0; I <array. size (); I ++)
{
A [I] = 1; // initialize the default Length
For (int j = 0; j <I; j ++) // The longest sequence above
{
If (array [I]> array [j] & a [j] + 1> a [I]) // The current number is larger than the j number, and the mark array needs to be updated.
{
A [I] = a [j] + 1;
}
}
}
Return Max (a, array. size ());
}
The time complexity of this method is O (N2 + N) = O (N2)
Solution 2
In the previous analysis, we did not consider the distribution of the first I + 1 element. Now we can analyze from another perspective, that is, when we examine the I + 1 element, we will consider the first I element.
For any incremental sub-sequence of the first I element, if the maximum element of this Sub-sequence is smaller than array [I + 1, then we can add array [I + 1] to the end of this subsequence to form a new incremental subsequence.
For example, when I = 4, the longest ascending sequence of the target sequence is 1,-1, 2,-3,-5, 6, and-7 is (1, 2), (-1, 2 ).
Then, as long as 4> 2, 4 can be directly added to the previous subsequence to form a new incremental subsequence.
Therefore, we hope to find an incremental sub-sequence of the first I element, so that the maximum element of this incremental sub-sequence is smaller than array [I + 1] and the length is as long as possible. After adding array [I + 1] to the incremental subsequence, you can find the longest incremental subsequence with array [I + 1] as the largest element.
It is still assumed that in the first I element of the array, the length of the longest incrementing sub-sequence with array [I] as the maximum element is LIS [I].
In addition, assume that:
The minimum value of the maximum element of an incremental sub-sequence with a length of 1 is MaxV [1].
The minimum value of the maximum element of an incremental sub-sequence with a length of 2 is MaxV [2].
......
The minimum value of the maximum element of an incremental sub-sequence with the length of LIS [I] Is MaxV [LIS [I].
This cycle is not variable. P is:
P: k is the length of the longest incrementing sub-sequence of sequence a [0: I], 0 ≤ I <n.
It is easy to see that in the loop from I-1 to I, the value of a [I] plays a key role. If a [I] can expand the length of the longest incrementing sub-sequence of sequence a [0; I-1], k = k + 1; otherwise k remains unchanged. Set the end element of the longest ascending subsequence with k length in a [0; I-1] to a [j] (0 ≤ j ≤ i-1 ), if a [I] is greater than or equal to a [j], it can be extended. Otherwise, it cannot be extended. If sequence a [0; I-1] has multiple longest incrementing subsequences with k lengths, what information needs to be stored? It is easy to see that as long as the minimum value of all the ending elements in the ascending subsequence of sequence a [0; I-1] k is stored, B [k]. Therefore, we need to enhance the loop-free P:
P: 0 ≤ I <n; k is the length of the longest ascending subsequence of sequence a [0; I;
B [k] is the minimum ending element value of all incremental subsequences with k length in sequence a [0; I.
Correspondingly, the induction hypothesis is also enhanced as follows: The length k of the longest ascending subsequence of known computing sequence a [0; I-1] (I <n) and sequence a [0; i] is the correct Algorithm for the minimum ending element value B [k] in all incremental subsequences with k length.
After the induction hypothesis is enhanced, in the cycle from I-1 to I, when a [I] Is ≥b [k], k = k + 1, B [k] = a [I]; otherwise, the k value remains unchanged. Note that when a [I] Is ≥b [k], the k value increases, and the value of B [k] is a [I]. So how should the value of B [l; k] be changed when a [I] <B [k? If a [I] <B [l], it is obvious that only a [I] of B [l] should be changed. when B [l] ≤ a [I] ≤ B [k], it is noted that array B is ordered and the subscript j can be found using the binary search algorithm, so that B [J-1] ≤ a [I] ≤ B [j]. At this time, the values of B [1; J-1] and B [j + 1; k] remain unchanged, and the values of B [j] are changed to a [I].Copy codeThe Code is as follows:/* Finds longest strictly increasing subsequence. O (n log k) algorithm .*/
Template <typename T> vector <int> find_lis (vector <T> &)
{
Vector <int> B, p (a. size (); // B is the subscript of the last element that stores the ascending sequence length of k.
// For example, B [1] is the subscript that stores the minimum value of the maximum element of the incremental subsequence.
// B is the subscript used to store the oldest sequence.
Int u, v;
If (a. size () <1)
Return B;
B. push_back (0 );
For (int I = 1; I <(int) a. size (); I ++)
{
If (a [B. back ()] <a [I])
{
P [I] = B. back ();
B. push_back (I );
Continue;
}
For (u = 0, v = B. size ()-1; u <v;) // Binary Search
{
Int c = (u + v)/2;
If (a [B [c] <a [I])
U = c + 1;
Else v = c;
}
If (a [I] <a [B [u])
{
If (u> 0)
P [I] = B [U-1];
B [u] = I;
}
}
For (u = B. size (), v = B. back (); u --; v = p [v])
B [u] = v;
Return B;
}