UVA 10635 Prince and Princess

题意描述:有两个长度分别为p+1和q+1的序列,每个元素中的各个元素互不相同。都是1~n^2之间的整数,求A和B的最长公共子序列。(2<=n<=250,1<=p,q<=n^2)

分析:本题是LCS问题,但因为p和q可以高达250^2=62500,O(pq)的算法显然太慢。注意到A序列中所有元素互不相同,因此可以把A中的元素重新编号为1~p+1。这样新的A和B的LCS实际上就是B的LIS。可以在O(nlogn)时间内解决。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int maxn=251*251;
 6 const int INF=1000000000;
 7 int s[maxn],g[maxn],d[maxn];
 8 int num[maxn];
 9 
10 int main()
11 {
12     int T;
13     scanf("%d",&T);
14     for(int kase=1;kase<=T;kase++)
15     {
16         int N,p,q,x;
17         scanf("%d %d %d",&N,&p,&q);
18         memset(num,0,sizeof(num));
19         for(int i=1;i<=p+1;i++) {scanf("%d",&x);num[x]=i;}
20         int n=0;
21         for(int i=0;i<q+1;i++) {scanf("%d",&x);if(num[x]) s[n++]=num[x];}
22         for(int i=1;i<=n;i++) g[i]=INF;
23         int ans=0;
24         for(int i=0;i<n;i++)
25         {
26             int k=lower_bound(g+1,g+1+n,s[i])-g;
27             d[i]=k;
28             g[k]=s[i];
29             ans=max(ans,d[i]);
30         }
31         printf("Case %d: %d
",kase,ans);
32     }
33     return 0;
34 }
原文地址:https://www.cnblogs.com/sage-blog/p/3648734.html