UVA 10635 Prince and Princess

本文介绍了一种将最长公共子序列(LCS)问题转化为最长递增子序列(LIS)问题的方法,并通过nlogn算法实现优化。通过重新编号及去除无效元素,有效地降低了算法的时间复杂度。

这题很明显的是LCS,不过p, q太大,普通的O(n ^ 2 )算法显然会超时

这里可以把LCS问题转换成LIS问题,LIS有nlogn的算法,然后复杂度就下来了.

因为每个序列都是没重复的,所以可以把序列1重新编号成1 - p + 1,然后序列2按照序列1的数字的对应编号进行转换.

例如:

序列1{1 7 5 4 8 3 9} 编号后变成{1 2 3 4 5 6 7}

序列2{1 4 3 5 6 2 8 9}转换后变成{1 4 6 0 3 0 0 5 7}

去掉转换后的序列2中的0,因为王子没有踩到这个格子.

对转换后的序列2求LIS就可以了.

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <memory.h>
using namespace std;
const int maxn = 62555;

int tb[maxn];
int A[maxn], d[maxn], g[maxn];
int p, q;
int main(){
	int T, trash, cas = 1;
	scanf("%d", &T);
	while(T--){
		scanf("%d%d%d", &trash, &p, &q);
		memset(tb, 0, sizeof(tb));
		for(int i = 0; i < p + 1; ++i){
			int t = 0;
			scanf("%d", &t);
			tb[t] = i + 1;
		}
		int n = 0, ans = 0; 
		for(int i = 0; i < q + 1; ++i){
			int t;
			scanf("%d", &t);
			if(tb[t]){
				A[n++] = tb[t];
			}
		}
		memset(g, 0X20, sizeof(g));
		for(int i = 0; i < n; ++i){
			int k = lower_bound(g + 1, g + n + 1, A[i]) - g;
			d[i] = k;
			g[k] = A[i];
			ans = max(ans, d[i]); 
		}
		printf("Case %d: %d\n", cas++, ans);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值