It is also a classic question in the training guide ~~
Http://uva.onlinejudge.org/external/106/10635.html
There are two sequences with the length of p + 1 and q + 1, each of which has different elements and is 1 ~ An integer of N ^ 2. Calculate the LCS of the two sequences.
Analysis: The O (PQ) Complexity of LCS is obviously too slow. Note that "each sequence has different elements and is 1 ~ N ^ 2 integer ", so there is a clever conversion, re-element in
By 1 ~ P + 1 number, and B is also the same ing number. Because a is an incremental sequence, LCS is the longest incremental subsequence of B, that is, Lis. in this way, the LIS problem of B can be converted.
Solved in O (nlogn) time.
LIS:
Set DP [I] to the length of the longest ascending subsequence ending with a [I.
O (N ^ 2) solution: DP [I] = max {0, DP [J] | j <I, AJ <AI} + 1;
O (nlogn) solution: Assume that two States A and B have met AA <AB and DP [a] = DP [B]; in this case, I select a in all subsequent states, which is not inferior to B. In this way, for the same Dp value, you only need to keep the smallest one of A (seeCode).
View code
1 /* 2 Author: zhaofa Fang 3 Lang: C ++ 4 */ 5 # Include <cstdio> 6 # Include <cstdlib> 7 # Include <sstream> 8 # Include <iostream> 9 # Include <cmath> 10 # Include <cstring> 11 # Include <algorithm> 12 # Include < String > 13 # Include <utility> 14 # Include <vector> 15 # Include <queue> 16 # Include <stack> 17 # Include <map> 18 # Include < Set > 19 Using Namespace STD; 20 21 Typedef Long Long Ll; 22 # Define Debug (x) cout <# x <':' <x <Endl 23 # Define Rep (I, n) for (INT I = 0; I <(n); I ++) 24 # Define For (I, S, T) for (INT I = (s); I <= (t); I ++) 25 # Define PII pair <int, int> 26 # Define PB push_back 27 # Define MP make_pair 28 # Define Fi first 29 # Define Se second 30 # Define Lowbit (x) (X & (-x )) 31 # Define INF (1 <30) 32 33 Const Int Maxn = 250 * 250 + 10 ; 34 Int A [maxn], B [maxn], POS [maxn], DP [maxn]; 35 36 Int Lis ( Int N) 37 { 38 For ( Int I = 1 ; I <= N; I ++) A [I] = inf, DP [I] = 0 ; 39 For ( Int I = 0 ; I <n; I ++ ) 40 { 41 Int K = lower_bound (a + 1 , A +1 + N, B [I])- A; 42 A [k] = B [I]; 43 DP [I] = K; 44 } 45 Int MX =- 1 ; 46 Rep (I, n) MX = Max (DP [I], MX ); 47 Return MX; 48 } 49 Int Main () 50 { 51 // Freopen ("in", "r", stdin ); 52 Int T; 53 Scanf ( " % D " ,& T ); 54 Rep (CAS, T) 55 { 56 Printf ( " Case % d: " , CAS + 1 ); 57 Int N, P, Q; 58 Scanf ( " % D " , & N, & P ,& Q ); 59 Memset (Pos, 0 , Sizeof (POS )); 60 Rep (I, P + 1 ) 61 { 62 Scanf ( " % D " ,& A [I]); 63 Pos [A [I] = I + 1 ; 64 } 65 Rep (I, q + 1 ) 66 { 67 Scanf ( " % D " ,& B [I]); 68 B [I] = Pos [B [I]; 69 } 70 Printf ( " % D \ n " , Lis (q + 1 )); 71 } 72 Return 0 ; 73 }