UVA 10635 Prince and Princess 最长公共子序列(nlongn)
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19051
题目意思是给你两串数字(计为 a,b 数组),让你求他们的最长公共子序列。数字长度是 n * n (n <= 250)所以 O(n^2) 肯定过不了了。所以想要找 O(nlongn)的。
因为题目给出了数字在 1 ~ (n^2)内并且数字不会重复。因此,对于a数组中的每个数字,如果我们都知道他在b数组中出先得位置的话(位置计为 c 数组),我们只需要在c数组里面求一个上升的子序列。而LIS是可以O(nlongn)做的。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int INF = 999999999; int a[62505]; int s[62505]; int dp[62505]; int main () { int T; cin >> T; for (int i_case = 1; i_case <= T; i_case++) { int n, _a, _b; cin >> n >> _a >> _b; memset(a, -1, sizeof a); for (int j=0; j<=_a; j++) { int tmp; scanf("%d", &tmp); a[tmp] = j; } for (int i=0; i<=_b; i++) { int tmp; scanf("%d", &tmp); s[i] = a[tmp]; } int k=0; for (int i=0; i<=_b; i++) { if (s[i] == -1) continue; s[k++] = s[i]; } fill (dp, dp + k, INF); for (int i=0; i < k; i++) { *lower_bound(dp, dp+k, s[i]) = s[i]; } printf("Case %d: %d\n", i_case, (int )(lower_bound(dp, dp+k, INF) - dp)); } return 0; }