UVA 10635 Prince and Princess LCS转LIS
题意:求最长公共子序列
正常的算法O(n^2)不够快,但因为这题数据特殊,数组中的数各不相同,可以转化成求最大上升子序列
比如样例中A{1 7 5 4 8 3 9}, B{1 4 3 5 6 2 8 9},将数字重新映射编号map[ai]=i;
ai=map[ai];bi=map[bi];
变成A{1,2,3,4,5,6,7} B{1,4,6,3,0,0,5,7} 问题便变成了求B的LIS可以在0(nlogn)求出
// #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> #include<sstream> #include<cmath> #include<climits> #include<string> #include<map> #include<queue> #include<vector> #include<stack> #include<set> using namespace std; typedef long long ll; typedef pair<int,int> pii; #define pb(a) push_back(a) #define INF 0x1f1f1f1f #define lson idx<<1,l,mid #define rson idx<<1|1,mid+1,r void debug() { #ifdef ONLINE_JUDGE #else freopen("d:\\in.txt","r",stdin); freopen("d:\\out1.txt","w",stdout); #endif } char getch() { char ch; while((ch=getchar())!=EOF) { if(ch!=' '&&ch!='\n')return ch; } return EOF; } struct point { int x,y,t; point() {} point (int a,int b,int e) { x=a; y=b; t=e; } bool operator < (point a) const { return t>a.t; } }; int da[70000]; int dp[70000]; int lis(int n) //LIS的O(nlogn)算法 { int maxx=1; dp[1]=da[1]; for(int i=2;i<=n;i++) { if(da[i]>=dp[maxx]) { dp[++maxx]=da[i]; } else { int v=upper_bound(dp+1,dp+1+maxx,da[i])-dp; dp[v]=da[i]; } } return maxx; } int main() { int t; scanf("%d",&t); for(int ca=1;ca<=t;ca++) { map<int,int> ma; int n,a,b; scanf("%d%d%d",&n,&a,&b); for(int i=1;i<=a+1;i++) { int x; scanf("%d",&x); ma[x]=i; } int k=0; for(int i=1;i<=b+1;i++) { int x; scanf("%d",&x); int v=ma[x]; if(v!=0)//0表示没出现,没必要加进去了 da[++k]=v; } int num=lis(k); printf("Case %d: %d\n",ca,num); } return 0; }