Storage extension Algorithm N2 programming C write a program that is as low as possible in a one-dimensional array (n elements) and the length of the longest increment subsequence.
For example, in a sequence 1,-1,2,-3,4,-5,6,-7, its longest incrementing sequence is 1,2,4,6 or -1,2,4,6. (The beauty of programming p198-202)
Analysis and solution
According to the requirements of the topic, the longest increment subsequence in a one-dimensional array is found, that is, to find a sequence of labels 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 One
According to the definition of no validity, we know that after each stage is arranged in a certain order, for a given stage state, the state of its previous stages can not directly affect its future decision, but only indirectly through the current state to affect. In other words, each state is a complete summary of history.
Again, in the case of sequence 1,-1,2,-3,4,-5,6,-7, after we find 4, we don't care about the two values before 4, because it has no direct effect on finding 6. Therefore, this problem satisfies no validity, and can be solved by using dynamic programming.
The target string can be analyzed by the law of numbers: 1,-1,2,-3,4,-5,6,-7.
Use I to represent the location of the current traversal
When I=1, it is obvious that the longest increment sequence is (1) and the sequence length is 1.
When I=2 is, due to -1<1. Therefore, you must discard the first value and then re-establish the string. The current increment sequence is (-1) and the length is 1.
When I=3, due to 2>1,2>-1. Therefore, the longest increment sequence is (1,2), ( -1,2), the length is 2. Here, the 2 front is 1 or-1 to find out the subsequent increment sequence has no direct effect. (but may be affected in other cases)
And so on, we come to the following conclusions.
Suppose that in the first I element of the target array array[], the length of the longest ascending subsequence 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 followed by a lis[k] long subsequence to form a longer subsequence. At the same time array[i+1] itself can constitute at least one subsequence of length 1.
Based on the above analysis, you can get a code listing:
C + + code:
Copy Code code 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;//initializes the default length
for (int j = 0; J < i; j + +)//front longest sequence
{
if (array [i] > array [j] && A[j] + 1 > A[i])//Current number is larger than J, and tag 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 Two
In the previous analysis, when we look at the i+1 element, we do not consider the distribution of the first element in the preceding section. Now we analyze from another angle, that is, when we look at the first element of i+1, we consider the case of the previous element.
For any ascending subsequence of the previous I element, if the largest element of the subsequence is smaller than array[i+1], then the array[i+1 is added to the subsequence, forming a new ascending subsequence.
For example, when i=4, the target sequence is the 1,-1,2,-3,4,-5,6,-7 maximum increment sequence (1,2), ( -1,2).
So, as long as 4>2, you can add 4 directly to the preceding subsequence to form a new ascending subsequence.
Therefore, we would like to find an ascending subsequence in the first I element so that the largest element of this increment sequence is smaller than array[i+1] and the length is as long as possible. This adds array[i+1] to the incrementing sequence, and then it can find the longest increment subsequence with array[i+1] as the maximum element.
It is still assumed that in the first I element of the array, the length of the longest incrementing sequence with array[i] as the maximum element is lis[i].
At the same time, suppose:
The minimum value of the maximum element of an ascending subsequence of length 1 is maxv[1];
The minimum value of the maximum element of an ascending subsequence of length 2 is maxv[2];
......
The minimum value of the maximum element of the ascending subsequence of the length lis[i] is maxv[lis[i]];
the invariant p of this loop is:
P:k is the length of the longest ascending subsequence of the sequence a[0:i], 0≤i<n.
It is easy to see that the value of a[i] plays a key role in the cycle from i-1 to I. If A[i] can extend the length of the longest ascending subsequence of the sequence a[0;i-1], then the K will be k=k+1. Set A[0;I-1] The end element of the longest incrementing substring of length k is a[j] (0≤j≤i-1), which can be extended when a[i]≥a[j, otherwise it cannot be extended. If the sequence a[0;i-1] has more than one longest increment subsequence of length k, what information is stored? It is easy to see that the minimum value b[k] of the end element in an ascending sequence of all lengths k in the storage sequence a[0;i-1]. Therefore, you need to enhance the cyclic invariant p to:
P:0≤i<n;k is the length of the longest ascending subsequence of the sequence a[0;i];
B[K] is the value of the smallest end element in an ascending subsequence of all lengths K in the sequence a[0;i.
Accordingly, the inductive assumption is also enhanced to the correct algorithm for the length k of the longest increment subsequence of the known computed sequence A[0;i-1] (i<n) and for the minimum end element value B[k in the sequence a[0;i] of all ascending sequences in the length K.
After strengthening the inductive assumption, in the cycle from i-1 to I, when A[i]≥b[k], k=k+1,b[k]=a[i], otherwise the K value does not change. Note that when A[i]≥b[k], the K value increases and the value of B[k] is a[i]. So, when A[i]<b[k], how should the value of b[l;k] change? If A[I]<B[L], then it is obvious that the b[l] only change to a[i], when b[l]≤a[i]≤b[k], note that array B is ordered, you can use the binary search algorithm to find subscript j, so that B[j-1]≤a[i]≤b[j]. At this point, the value of b[1;j-1] and b[j+1;k] is unchanged, and the value of B[j] is changed to A[i].
Copy Code code as follows:
/* finds longest strictly increasing subsequence. O (n log k) algorithm. */
Template<typename t> vector<int> find_lis (vector<t> &a)
{
Vector<int> B, P (A.size ());//b is the last element subscript for storing the increment sequence length k
For example, B[1] is the subscript that stores the minimum value of the maximum element of the incrementing subsequence
B is the subscript that stores the oldest firstborn 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;)//two min 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;
}