https://vjudge.net/problem/UVA-10635
题意:
有两个长度分别为p+1和q+1的序列,每个序列中的各个元素互不相同,且都是1~n^2之间的整数。两个序列的第一个元素均为1,。求出A和B的最长公共子序列长度。
思路:
因为序列中元素各不相同,所以我们可以把A重新编号为{1,2,3,4,5...},也就是相当于映射,之后B根据A映射,最后在B中找LIS即可。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<vector> 6 #include<stack> 7 #include<queue> 8 #include<cmath> 9 #include<map> 10 using namespace std; 11 typedef long long LL; 12 typedef pair<int,int> pll; 13 const int INF=0x3f3f3f3f; 14 const int maxn=250*250; 15 16 int n,p,q; 17 int num[maxn],s[maxn]; 18 int d[maxn],g[maxn]; 19 20 int main() 21 { 22 //freopen("D:\input.txt","r",stdin); 23 int kase=0; 24 int T; 25 scanf("%d",&T); 26 while(T--) 27 { 28 memset(num,0,sizeof(num)); 29 scanf("%d%d%d",&n,&p,&q); 30 31 for(int i=1;i<=p+1;i++) 32 { 33 int x; 34 scanf("%d",&x); 35 num[x]=i; 36 } 37 38 int cnt=0; 39 for(int i=0;i<q+1;i++) 40 { 41 int x; 42 scanf("%d",&x); 43 if(num[x]) s[cnt++]=num[x]; 44 } 45 46 int ans=0; 47 for(int i=1;i<=cnt;i++) g[i]=INF; 48 for(int i=0;i<cnt;i++) 49 { 50 int k=lower_bound(g+1,g+cnt+1,s[i])-g; 51 d[i]=k; 52 g[k]=s[i]; 53 ans=max(ans,d[i]); 54 } 55 printf("Case %d: %d ",++kase,ans); 56 } 57 return 0; 58 }