Shuoj1936-D sequence-longest ascending subsequence, shuoj1936-d Sequence
Description
We know two arrays A and B whose lengths are N, and the subscript ranges from 0 to N-1.
A d sequence (assuming the length is L) is defined to meet the following conditions:
1. 0 <= D [I] <= N-1
2. A [D [I] <A [D [I + 1] (0 <= I <L-1)
3. B [D [I]> B [D [I + 1] (0 <= I <L-1)
Obtain the maximum length of the D sequence that meets the condition.
(In fact, this sequence is called D sequence because: This question is D)
Input
Multiple groups of data. The first row of each group is an integer N. (1 <= N <= 100000)
The second row contains N positive integers A [0] ~ A [N-1].
The third row contains N positive integers B [0] ~ B [N-1].
Make sure that all input integers are within the int range.
Output
For each group of data, an integer is output, indicating the maximum length of the D sequence.
Sample Input31 1 23 2 131 2 141 3 2 43 1 2 4
Sample Output
233
Idea: Sort array A and array B in ascending order with the first keyword A and the second keyword B, and then invert B to find the longest ascending subsequence of B. To avoid subscript sorting and write comparison functions, save a B in pair and sort it first, and then extract it and enlarge it to. Invert the image and find the oldest sequence. When the longest ascending subsequence is obtained, the time complexity of using the dp Method is O (n ^ 2), which times out. Therefore, other methods are used. Method (1): Use lower_bound to find the ascending sub-sequence O (nlogn) // lower_bound. The three parameters are respectively the start point address to be compared, the end point address + 1 (that is, left closed and right open), the value to be compared (assumed as d ). // Its function is to return an address, which is the minimum value of> = d in the comparison range. // For example, a [] = {0, 1, 2, 4, 5, 7} p = lower_bound (a, a + 6, 3 ), p is the 4 address. If p = lower_bound (a, a + 6, 4), p is also the 4 address method (2 ):: the binary method is used to calculate the ascending sub-sequence O (nlogn). lower_bound is used to compare the number in the array. When the number to be compared is large, the number cannot be saved in the array, however, this problem can be solved by using the binary method, but the code is difficult. The two methods have the same idea. Store the minimum value of the length of the neutron sequence of array A as I in array S. We use 3, 2, 4, 6, 7, 3 as an example to demonstrate behavior traversal. The column is an array of S, and the changes have been marked out to help you understand. Here, a [I]> s [j] & a [I] <= s [j + 1] should put a [I] in s [j + 1] location. So the key is to find j and know where a [I] is put. The above two methods are used to find j. (Here lower_bound returns j + 1 directly.) We can find that the values in the s array must increase sequentially, which is also a necessary condition for the use of the binary method.
Demo
0 |
1 |
2 |
3 |
4 |
1 |
3 |
|
|
|
2 |
2 |
|
|
|
3 |
2 |
4 |
|
|
4 |
2 |
4 |
6 |
|
5 |
2 |
4 |
5 |
|
6 |
2 |
4 |
5 |
7 |
7 |
2 |
3 |
5 |
7 |
|
|
|
|
|
Method (1) code ::
# Include <bits/stdc ++. h> using namespace std; int a [100005], B [100005]; int s [100005]; vector <pair <int, int> T; // It can be saved using a vector, or directly using the array pair <int, int> T [100005]; int main () {int n; while (~ Scanf ("% d", & n) {T. clear (); // for (int I = 0; I <n; I ++) scanf ("% d ", & a [I]); for (int I = 0; I <n; I ++) scanf ("% d", & B [I]); // If an array is used, it should be T [I] = {a [I], B [I]}; for (int I = 0; I <n; I ++) t. push_back (make_pair (a [I], B [I]); // sort (T, T + n); std: sort (T. begin (), T. end (); // sort for (int I = 0; I <n; I ++) a [I] = T [I]. second; // extract the sorted array B and put it in a reverse (a, a + n); // cause int len = 1; s [1] = a [0]; // <span style = "font-family: Arial, Helvetica, sans-serif; "> put the first element into the idea of s [1] </span> for (int I = 1; I <n; I ++) {// dp, add the elements in a to s one by one. int t = a [I]; if (t> s [len]) s [++ len] = a [I]; else {int p = lower_bound (s + 1, s + len + 1, t)-s; s [p] = t ;}} printf ("% d \ n", len);} return 0 ;}
Method (2) code ::
# Include <bits/stdc ++. h> using namespace std; int a [100005], B [100005]; int s [100005]; vector <pair <int, int> T; int main () {int n; while (~ Scanf ("% d", & n) {T. clear (); for (int I = 0; I <n; I ++) scanf ("% d", & a [I]); for (int I = 0; I <n; I ++) scanf ("% d", & B [I]); for (int I = 0; I <n; I ++) T. push_back (make_pair (a [I], B [I]); std: sort (T. begin (), T. end (); for (int I = 0; I <n; I ++) a [I] = T [I]. second; reverse (a, a + n); int len = 1; s [1] = a [0]; for (int I = 1; I <n; I ++) {int t = a [I]; if (t> s [len]) s [++ len] = a [I]; else {int l = 1, r = len, mid; int ans = 0; while (l <= r) // here, the binary method uses the left-closed and right-closed logic {mid = (r + l)/2; if (s [mid] <t) {l = mid + 1; ans = max (ans, mid); // ans is j in the idea, and j must be the maximum number of s arrays smaller than t} else r = mid-1 ;} s [ans + 1] = t;} printf ("% d \ n", len);} return 0 ;}
Copyright statement: You can browse it at will.