题目链接:http://vjudge.net/contest/137498#problem/G
题意:有两个长度为p+1和q+1的序列,每个序列的中的各个元素互不相同,且都是1~n^2之间的整。两个序列的第一个元素均为1。求出A和B的最长公共子序列长度。
输入: T //测试组数
n p q
A : p+1个数
B:q+1个数
输出:Case t: len
思路:因为n*n=62500 LCS的算法 O(pq)很慢,而且数组也开不下,所以可以转化为求LIS(O(nlogn))。
代码:
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn=62505; const int INF=1000000000; int s[maxn],dp[maxn]; int num[maxn]; /// num[x]为整数x的新编号,num[x]=0表示x没有在A中出现过 int main() { int T; scanf("%d",&T); for(int t=1; t<=T; t++) { int N,p,q,x; scanf("%d%d%d",&N,&p,&q); memset(num,0,sizeof(num)); for(int i=1; i<=p+1; i++) { scanf("%d",&x); num[x]=i; } int n=0; for(int i=0; i<q+1; i++) ///转化为求s的LIS { scanf("%d",&x); if(num[x]) s[++n]=num[x]; } int len=1; dp[1]=s[1]; for(int i=2; i<=n; i++) { if(s[i]>dp[len]) dp[++len]=s[i]; else dp[upper_bound(dp+1,dp+1+len,s[i])-dp]=s[i]; } printf("Case %d: %d\n",t,len); } return 0; }