UVa 10635 王子和公主(LCS转LIS)

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 }
原文地址:https://www.cnblogs.com/zyb993963526/p/6919816.html