您的位置:首页 > 其它

[LCS][LIS]Uva10635]

2016-11-07 21:15 288 查看
题目大意:求两个序列的LCS

一般来说,LCS复杂度O(n*n)

f[i][j]表示A串前i个,B串前j个的LCS

f[i][j]=f[i-1][j-1] (s1[i]==s2[j])

f[i][j]=max(f[i-1] [j],f[i][j-1])

但是

Input

The rst line of the input contains a single integer t (1  t  10), the number of test cases followed.

For each case, the rst line contains three integers n, p, q (2  n  250, 1  p; q < n  n). The second

line contains p + 1 different integers in the range [1 : : : n  n], the sequence of the Prince. The third line

contains q + 1 different integers in the range [1 : : : n  n], the sequence of the Princess.

Output

For each test case, print the case number and the length of longest route. Look at the output for sample

input for details.

Sample Input

1

3 6 7

1 7 5 4 8 3 9

1 4 3 5 6 2 8 9

Sample Output

Case 1: 4

N是250*250,,所以n*n会爆掉,而且序列又不相同

所以可以把LCS转成LIS,,,

LCS->LIS原则:序列中字母或者数字各不相等。

做法:第一个序列映射,,转换第二个序列

1 5 3 7 2=1 2 3 4 5

5 9 3 7 2 1=2 0 3 4 5 1

注意,只有当找得到的映射才能计算,判断

复杂度:n*logn

#include<iostream>
#include<cstdio>
#include<ctime>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<string>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
#define INF 0x3f3f3f3f
#define clock CLOCKS_PER_SEC
#define cle(x) memset(x,0,sizeof(x))
#define maxcle(x) memset(x,127,sizeof(x))
#define mincle(x) memset(x,-1,sizeof(x))
#define cop(a,x) memcpy(x,a,sizeof(a))
#define FROP "Uva"
#define C(a,b) next_permutation(a,b)
#define LL long long
#define smin(x,tmp) x=min(x,tmp)
using namespace std;
const int N=655;
int mp[N*N],last[N*N],kase;
int a[N*N],b[N*N],ans;
int find(int x)
{
int l=1,r=ans,tmp=0;
while(l<=r)
{
int mid=(l+r)>>1;
if(last[mid]<=x)tmp=mid,l=mid+1;
else r=mid-1;
}
return tmp;
}
int main()
{
freopen(FROP".in","r",stdin);
freopen(FROP".out","w",stdout);
int t;
scanf("%d",&t);
while(t--)
{
cle(a),cle(b),cle(mp),maxcle(last);
int n,q,p;
scanf("%d%d%d",&n,&q,&p);
p++,q++;
for(int i = 1; i<= q; i++)
scanf("%d",&a[i]),mp[a[i]]=i;
int pos=0;
for(int i = 1; i<= p; i++)
{
int x;
scanf("%d",&x);
if(mp[x])b[++pos]=mp[x];
}
ans=0;
for(int i = 1 ; i <= pos; i++)
{
int tmp=find(b[i]);
if(last[tmp+1]>b[i])last[tmp+1]=b[i];
ans=max(tmp+1,ans);
}
kase++;
printf("Case %d: %d\n",kase,ans);
}
return 0;
}


调了很久,,发现数组开小了。。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  uva