题目传送:UVA - 10635
思路:直接思路是两个串的LCS,不过这个题可以转化为LIS,因为说了序列中各个元素互不相同,所以可以来个映射算出第二个字符串中的字符对应第一个字符串中字符的位置(不存在即删去),然后算出这些位置的LIS即可
AC代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <deque>
#include <cctype>
#define LL long long
#define INF 0x7fffffff
using namespace std;
const int maxn = 250 * 250 + 10;
int S[maxn], g[maxn];
int num[maxn];//记录第一个数组中每个数字出现的位置
int N, p, q;
int main() {
int T;
int cas = 1;
scanf("%d", &T);
while(T --) {
scanf("%d %d %d", &N, &p, &q);
memset(num, 0, sizeof(num));
for(int i = 1; i <= p + 1; i ++) {
int t;
scanf("%d", &t);
num[t] = i;
}
int n = 0;
for(int i = 1; i <= q + 1; i ++) {
int t;
scanf("%d", &t);
if(num[t] != 0) {
S[n ++] = num[t];
}
}
//n*logn求S数组的LIS
for(int i = 1; i <= n; i ++) g[i] = INF;
int ans = 0;
for(int i = 0; i < n; i ++) {
int pos = lower_bound(g + 1, g + n + 1, S[i]) - g;//n*logn查找
g[pos] = S[i];
ans = max(ans, pos);
}
printf("Case %d: %d\n", cas ++, ans);
}
return 0;
}