您的位置:首页 > 其它

UVa 10635 (LIS+二分) Prince and Princess

2014-08-08 08:49 363 查看
题目的本意是求LCS,但由于每个序列的元素各不相同,所以将A序列重新编号{1,2,,,p+1},将B序列重新编号,分别为B中的元素在A中对应出现的位置(没有的话就是0)。

在样例中就是A = {1 7 5 4 8 3 9},B = {1 4 3 5 6 2 8 9}

重新编号以后:

A = {1 2 3 4 5 6 7}, B = {1 4 6 3 0 0 5 7}(里面的0在求LIS时可以忽略)

这样求A、B的LCS就转变为求B的LIS

求LIS用二分优化,时间复杂度为O(nlogn)

第一次做的用二分求LIS的题是HDU 1025
http://www.cnblogs.com/AOQNRMGYXLMV/p/3862139.html
在这里再复习一遍

//#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int INF = 1000000000;
const int maxn = 250 * 250;
int num[maxn], s[maxn], g[maxn], d[maxn];

int main(void)
{
#ifdef LOCAL
freopen("10635in.txt", "r", stdin);
#endif

int T, kase;
scanf("%d", &T);
for(kase = 1; kase <= T; ++kase)
{
int N, p, q, x;
scanf("%d%d%d", &N, &p, &q);
memset(num, 0, sizeof(num));
for(int i = 1; i <= p+1; ++i)
{
scanf("%d", &x);
num[x] = i;
}
int n = 0;
for(int i = 1; i <= q+1; ++i)
{
scanf("%d", &x);
if(num[x])
s[n++] = num[x];
}
//求s[1]...s
的LIS
for(int i = 1; i <= n; ++i)
g[i] = INF;
int ans = 0;
for(int i = 0; i < n; ++i)
{
int k = lower_bound(g+1, g+n+1, s[i]) - g;
d[i] = k;
g[k] = s[i];
ans = max(ans, d[i]);
}
printf("Case %d: %d\n", kase, ans);
}
return 0;
}


代码君
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: