uva10635 王子和公主(把lcs转化为lis)

有两个长度为p+1和q+1的序列,每个序列中的各个元素互不相同,且都是1~n*n之间的整数,两个序列的第一个元素都是1,求a和b的最长公共子序列的长度。

思路很容易想到lcs,但是由于O(pq)的算法肯定会超时,所以不能采用,注意到a和b中的元素互不相同,故可以预处理a中的元素,用trans数组记录a每个元素值对应的位置,然后处理b中的元素,把每个元素转化成该元素在a中的位置,如果没在a中出现那么为零,这样就把lcs问题转化成了lis

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#define eps 1e-6
#define LL long long
using namespace std;  

const int maxn = 250 * 250 + 50;
const int INF = 0x3f3f3f3f;
int n, p, q;
int B[maxn], trans[maxn], g[maxn], d[maxn];
int kase = 0;

void init() {
	scanf("%d%d%d", &n, &p, &q);
	memset(trans, 0, sizeof(trans));
	for(int i = 1; i <= p+1; i++) {
		int tmp; scanf("%d", &tmp);
		trans[tmp] = i;
	}
	for(int i = 0; i <= q; i++) {
		int tmp; scanf("%d", &tmp);
		B[i] = trans[tmp];
	}
}

void solve() {
	int ans = -INF;
	for(int i = 1; i <= q+1; i++) g[i] = INF;
	for(int i = 0; i <= q; i++) {
		int k = lower_bound(g+1, g+q+2, B[i]) - g;
		d[i] = k;
		g[k] = B[i];
	}
	for(int i = 0; i <= q; i++) ans = max(ans, d[i]);
	printf("Case %d: %d\n", ++kase, ans);
}

int main() {
	freopen("input.txt", "r", stdin);
	int t; scanf("%d", &t);
	while(t--) {
		init();
		solve();
	}
	return 0;
}
时间: 2024-10-08 12:06:07

uva10635 王子和公主(把lcs转化为lis)的相关文章

王子和公主 UVa10635

[题目描述]:王子和公主 一个王子和公主在n*n的格子中行走,这些格子是有1....n^2的编号的.现在给定p+1个数,再给定q+1个数,公主和王子可以选择其中某些格子行走,求他们最多能走几个相同的格子. [算法分析]: 这道题读题是关键,然后我们发现需要的是公共的格子,又需要是这个步数最大化,可以想到最长公共子序列的模型.序列长度小于等于62500,最长公共子序列复杂度是n^2,超时.然而可以巧妙的将LCS转化为LIS,使用nlogn的方法求解 解题思路:本题是一道经典的题目,巧妙的将LCS问

UVA - 10635 - Prince and Princess (LCS转化为LIS)

题目传送:UVA - 10635 思路:直接思路是两个串的LCS,不过这个题可以转化为LIS,因为说了序列中各个元素互不相同,所以可以来个映射算出第二个字符串中的字符对应第一个字符串中字符的位置(不存在即删去),然后算出这些位置的LIS即可 AC代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #in

王子和公主

题意简化一下,这道题还是比较不错的,虽然我还没有实现过,不过我是已经理解了. 题意:有两个长度分别为p+1和q+1的序列,每个序列中的各个元素互不相同,且都是1-n^2之间的整数,两个序列的第一个元素均为1,求A和B的最长公共子序列的长度. T<=10 2<=N<=250 这道题是一道LCS的题,但是最快的LCS的速度也为O(pq)62500^2这个是过不了的,所以从题目的特殊性考虑如何解这道题,发现序列中的各个元素互不相同,这有什么用呢? 可以将它重新标号,如A={1,7,5,4,8,

动态规划 最长公共子序列 王子和公主 Prince and Princess UVa 10635

#include <iostream> #include <algorithm> using namespace std; const int maxn = 250 * 250; int main(){ char T; cin >> T; for (char k = 0; k < T;k++) { int n, p, q; cin >> n >> p >> q; int num[maxn]; memset(num, 0, siz

王子和公主的童话

http://club.jd.com/CommunityGroupDetail/25094575_1.html http://club.jd.com/CommunityGroupDetail/25094786_1.html http://club.jd.com/CommunityGroupDetail/25094864_1.html http://club.jd.com/CommunityGroupDetail/25094733_1.html http://club.jd.com/Communi

uva10635 LCS映射转LIS

题目给定 2个序列,要我们求LCS,但是序列的长度最长是250*250, LCS的时间复杂度是O(N*N),所以无法解决 我们可以第一个序列的数字,按位置,映射为1.2.3.4.5.6.7.8.9 那么就会得到一个映射函数,将第二个序列,映射为一个新的序列 那么就相当于用一个映射函数将两个字符串映射为两个新的字符串 我们会发现,LCS的长度是不会改变的 因为两个序列中相同的字符映射之后仍然相同 所以只要求两个序列的LCS即可 然后我们发现,第一个序列是递增的,那么求出来的LCS肯定也是递增的 那

UVA10635 Prince and Princess(LIS)

题意:王子和公主同时从1出发走到 n*n, 求他们两个路径的最长公共子序列: 思路:因为这题n有250,如果用LCS负责度为O(n^2),容易超时,于是我们选择它的优化版Lis算法来求最长公共子序列,这样我们的复杂度就降为O(n*logn)了. Lis算法: 先回顾经典的O(n^2)的动态规划算法,设A[t]表示序列中的第t个数,F[t]表示从1到t这一段中以t结尾的最长上升子序列的长度,初始时设F[t] = 0(t = 1, 2, ..., len(A)).则有动态规划方程:F[t] = ma

[转]王垠的过去和现状

王垠的过去和现状 我曾在2006年冬季接触到王垠的三篇文章:<完全用linux工作>.<写给支持和反对<完全用Linux工作>的人们>.<清华梦的粉碎--写给清华大学的退学申请>,今天巧合又再次读遍,于是决定把我知道关于王垠的信息总结一下. 1. 从清华退学 王垠是高考发挥失常进入四川大学计算机系97级(据此推测他是79.80生人):2001年直接保送到清华大学计算机系软件所硕博连读,主要进行集成电路布线算法的研究. 2004年8月左右[1],王垠完成了&l

聚焦新相亲时代:女孩在京有五六套房哭着想嫁富2代

2017-09-20 07:31:00 来源: 中国青年报(北京)        举报 6984 分享到: 易信 微信 QQ空间 微博 更多 用微信扫码二维码 分享至好友和朋友圈 T + - (原标题:中青报聚焦新相亲时代:2亿人及其背后家庭组成的"擂台") 石家庄某相亲角.视觉中国 资料 平均算下来,每一分钟里,国内有22对新人拿着户口本走向民政局,进入婚姻生活:同时,8对夫妻在另外一个窗口签下离婚协议. 根据民政部公布的数字,中国的结婚率和离婚率曲线渐渐逼近一个闭合的大于号.婚姻的