Longest Ordered Subsequence (Longest monotonic increasing Subsequence) poj2533 + Dynamic Planning
Longest Ordered Subsequence
Time Limit:2000 MS |
|
Memory Limit:65536 K |
Total Submissions:40309 |
|
Accepted:17743 |
Description
A numeric sequence
AiIs ordered if
A1<
A2<... <
AN. Let the subsequence of the given numeric sequence (
A1,
A2,...,
AN) Be any sequence (
Ai1,
Ai2,...,
AiK), Where 1 <=
I1<
I2<... <
IK<=
N. For example, sequence (1, 7, 3, 5, 9, 4, 8) has ordered subsequences, e. g ., (1, 7), (3, 4, 8) and other others. all longest ordered subsequences are of length 4, e. g ., (1, 3, 5, 8 ).
Your program, when given the numeric sequence, must find the length of its longest ordered subsequence.
Input
The first line of input file contains the length of sequence N. the second line contains the elements of sequence-N integers in the range from 0 to 10000 each, separated by spaces. 1 <= N <= 1000
Output
Output file must contain a single integer-the length of the longest ordered subsequence of the given sequence.
Sample Input
71 7 3 5 9 4 8
Sample Output
4
Source
Northeastern Europe 2002, Far-Eastern Subregion
From http://www.cnblogs.com/liyukuneed/archive/2013/05/26/3090402.html
This blog will continue to solve the problem of upgrading-the longest incrementing subsequence
Problem definition:
Given an array with a length of N, find the longest monotonic auto-incrementing subsequence (not necessarily continuous, but the sequence cannot be messy ). For example, if an array A {5, 6, 7, 1, 2, 8} with A length of 6 is given, the longest monotonic increasing subsequence is {5, 6, 7, 8 }, the length is 4.
Solution 1: Longest Common subsequence method:
If you think carefully about the above problems, you can actually convert the above problems into the problem of finding the longest public subsequence. The original array is A {5, 6, 7, 1, 2, 8}. Next, we sort the array. The sorted array is a' {1, 2, 5, 6, 7, 8 }. After we have two arrays like this, if we want to find the longest incrementing subsequence of array A, it is actually the longest common subsequence of array A and its sort array. Let me think about several elements of the original problem: longest, increasing, and subsequence (I .e., the sequence remains unchanged ).
Increment: The a' array is an ascending sort array, which ensures the incrementing feature of the longest common subsequences of the two sequences.
Sub-sequence: Since array A is the original array, any sub-sequence of the sub-sequence remains the same, so that the order of the longest common sub-sequence of the two sequences remains unchanged.
Longest: Obvious.
Solution 2: Dynamic Programming (O (N ^ 2 ))
Since it is a dynamic programming method, the most important thing is to find a subproblem. For this problem, we find its subproblem:
For arrays A [N] = {a0, a1, a2 ,..., an-1}. Suppose we want to find the maximum incrementing sub-sequence length ending with aj and set it to L [j], then L [j] = max (L [I]) + 1, where I <j & a [I] <a [j], that is, the range of I is 0 to j-1. In this way, to find the length of the largest incrementing sub-sequence ending with aj, We need to traverse all the positions before j I (0 to J-1 ), find a [I] <a [j], calculate the I that can generate the largest L [I], and then obtain L [j]. Then I calculate the length of the maximum incrementing sub-sequence ending with each element in A [N], the maximum length of these sub-sequences, this is the problem we require-the maximum incrementing subsequence of array.
Time Complexity: Since each time is compared with all the previous I, the time complexity is O (N ^ 2 ).
Solution 3: Dynamic Programming (O (NlogN ))
The time complexity of the preceding solution is still O (N ^ 2), which is no significant difference from solution 1. After careful analysis, the reason is slow because every new position j needs to traverse the previous position j and find the longest ascending length of the subsequence. Is there a way to determine the I location faster without traversing all the previous locations?
In this case, we need to apply for a space with a length of N, B [N], and use the variable len to record the length of the longest incrementing subsequence.
Any element B [I] in array B records the value of the end element of the sequence with the longest incrementing sub-sequence length of I, that is, the maximum element size value of the longest incrementing subsequence.
First, put d [1] In B order, so that B [1] = 2, that is, when there is only 1 digit 2, the minimum end of LIS with a length of 1 is 2. Then Len = 1
Then, Put d [2] in B order, so that B [1] = 1, that is, the minimum end of LIS with a length of 1 is 1, d [1] = 2 is useless. It's easy to understand. Then Len = 1
Then, d [3] = 5, d [3]> B [1], so that B [1 + 1] = B [2] = d [3] = 5, that is to say, the minimum end of LIS with a length of 2 is 5, which is easy to understand. At this time, B [1 .. 2] = 1, 5, Len = 2
Again, d [4] = 3, which is exactly between and 5. It is obviously not suitable to place it at the position of 1, because 1 is smaller than 3, and the minimum end of LIS with a length of 1 should be 1, it is easy to infer that the minimum end of LIS with a length of 2 is 3, so 5 can be eliminated. At this time, B [1 .. 2] = 1, 3, Len = 2
Continue, d [5] = 6, it is behind 3, because B [2] = 3, and 6 is behind 3, so it is easy to know that B [3] = 6, B [1 .. 3] = 1, 3, 6. Is it easy to understand? Len = 3.
6th, d [6] = 4. You can see it is between 3 and 6, so we can replace 6 and get B [3] = 4. B [1 .. 3] = 1, 3, 4, Len continues to be 3
7th, d [7] = 8, it's big, bigger than 4, um. So B [4] = 8. Len becomes 4
8th, d [8] = 9, and B [5] = 9, um. Len continues to increase to 5.
The last one, d [9] = 7, 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 that the LIS length is 5.
Note that this 1, 3, 4, 7, 9 is not LIS, it is only the minimum end of the storage of the corresponding length LIS. With this end, We can insert data one by one. Although the last d [9] = 7 is meaningless for this group of data, if there are two numbers 8 and 9, then we can update 8 to d [5], 9 to d [6], and obtain that the LIS length is 6.
Then we should find one thing: inserting data in B is ordered, and it is replaced without moving-that is, we can use binary search, optimize the insertion time of each number to O (logN )~~~~~ So the time complexity of the algorithm is reduced to O (NlogN )~!
According to the above analysis, the following is the C ++ code implementation of the last two methods:
# Include
# Include
Using namespace std; int num [1, 1005]; int main () {int n; while (scanf (% d, & n) = 1) {int tmp, mmax; scanf (% d, & tmp); mmax = tmp; int arr [1005]; // used to store the incremental sequence, which has no practical significance. arr [0] = tmp; int cnt = 0; for (int I = 1; I
Tmp) {int left = 0; int right = cnt; while (left <= right) // pay attention to the equal sign {int mid = (left + right)/2; if (arr [mid]
Tmp) right = mid-1; if (arr [mid] = tmp) {left = mid; break;} arr [left] = tmp ;}} /** for (int I = 0; I <= cnt; I ++) {printf (% d, arr [I]);} printf (); */printf (% d, cnt + 1);} return 0;}/** 71 7 3 5 9 4 8102 1 3 4 6 100 101 7 8 9 */