10635 - Prince and Princess

/*
题意:T组测试,输入n,p,q ,接下来两行,
第一行 p +1 个数,第二行 q + 1个数,这些数都在 N*N范围内 。
找出最长公共子序列。

因为 p,q范围较大,如果用 p*q 的做法会超时,
看了题解后知道了可以转成 LIS 来求,LIS 只要 NlonN 就可以辣。

*/

LCS转LIS,这里摘抄一段,
原文出自 “[email protected]” 博客, http://karsbin.blog.51cto.com/1156716/966387

举例说明:
A:abdba
B:dbaaba
则1:先顺序扫描A串,取其在B串的所有位置:
2:a(2,3,5) b(1,4) d(0)。
3:用每个字母的反序列替换,则最终的最长严格递增子序列的长度即为解。
替换结果:532 41 0 41 532
最大长度为3.
简单说明:上面的序列和最长公共子串是等价的。
对于一个满足最长严格递增子序列的序列,该序列必对应一个匹配的子串。
反序是为了在递增子串中,每个字母对应的序列最多只有一个被选出。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define MAX 250
 5 using namespace std;
 6 int sq[MAX*MAX+5],num[MAX*MAX+5],h[MAX*MAX+5];
 7 int Find(int c[],int len,int x)
 8 {
 9     int l=0,r=len,mid=(l+r)/2;
10     while(l<=r)
11     {
12         if(x<c[mid]) r -= 1;
13         else if(x>c[mid]) l += 1;
14         else return mid;
15         mid = (l+r)/2;
16     }
17     return l;
18 }
19 int main()
20 {
21     int cnt=0,t,n,p,q,y;
22     scanf("%d",&t);
23     while(t--)
24     {
25         int c=0;
26         scanf("%d%d%d",&n,&p,&q);
27         memset(num,0,sizeof(num));
28         for(int i=1;i<=p+1;i++)
29         {
30             scanf("%d",&y);
31             num[y]=i;
32         }
33         for(int i=0;i<q+1;i++)
34         {
35             scanf("%d",&y);
36             if(num[y])
37                 sq[c++]=num[y];
38         }
39         int len=1;
40         h[0] = -999999999;
41         h[1] = sq[0];
42         for(int i=1;i<c;i++)
43         {
44             int x = Find(h,len,sq[i]);
45             h[x] = sq[i];
46             if(x>len) len = x;
47         }
48         printf("Case %d: %d\n",++cnt,len);
49     }
50     return 0;
51 }
时间: 2024-07-30 21:33:26

10635 - Prince and Princess的相关文章

uva 10635 Prince and Princess(DP)

uva 10635 Prince and Princess(DP) In an n x n chessboard, Prince and Princess plays a game. The squares in the chessboard are numbered 1, 2, 3 ... n*n, as shown below: Prince stands in square 1, make p jumps and finally reach square n*n. He enters a

uva 10635 Prince and Princess(LCS问题转化成LIS问题O(nlogn))

题目大意:有两个长度分别为p+1和q+1的序列,每个序列中的各个元素互不相同,且都是1~n^2之间的整数.两个序列的第一个元素均为1.求出A和B的最长公共子序列长度. 分析:本题是LCS问题,但是p*q<=62500,O(pq)的算法显然会LE.在这里有一个条件,每个序列中的各个元素互不相同,所以可以把A中元素重新编号为1~p+1.例如,样例中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

算法竞赛与入门经典---P66 [UVA 10635] Prince and Princess

Prince and PrincessInput: Standard Input Output: Standard Output Time Limit: 3 Seconds In an n x n chessboard, Prince and Princess plays a game. The squares in the chessboard are numbered 1, 2, 3 ... n*n, as shown below: Prince stands in square 1, ma

UVa 10635 - Prince and Princess

题目:在一个n*n的棋盘上,格子标号1~n*n,现在有两个人从1跳到n*n(不走重复点), 现在要求去掉最少的中间点,使得路径是一样的. 分析:dp,LIS,LCS.问题是求最大公共子序列,数据较大需要O(nlgn)算法. 发现题目中的数据是不重复的,所以可以转化成最大上升子序列: 记录序列1中每个元素对应的顺序,将序列2中的元素转化成对应序列1中的顺序标号: 那么,新构成的序列2中递增的序列即为序列1中的先后顺序,所以求出它的LIS即可. 说明:╮(╯▽╰)╭. #include <algor

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

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

UVA - 10635 —— Prince and Princess

题目:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19051 首先,这题一看就知道是——最长公共子序列(LCS) 但是,会发现这道题的字符串长度可能达到62500,我们现在会的LCS的解法时间复杂度为O(n^2),所以是会超时的. 那么,这时候就要想:题目有没有给出更多的条件给我们,让我们能够在更快地时间内完成任务呢? 还真有!题目有一个反复强调的条件,就是:一个字符串的全部字符都是不同的! 所以,我们可以这样: (1)

UVA 10635 Prince and Princess 最长公共子序列(nlongn)

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19051 题目意思是给你两串数字(计为 a,b 数组),让你求他们的最长公共子序列.数字长度是 n * n (n <= 250)所以 O(n^2) 肯定过不了了.所以想要找 O(nlongn)的. 因为题目给出了数字在 1 ~ (n^2)内并且数字不会重复.因此,对于a数组中的每个数字,如果我们都知道他在b数组中出先得位置的话(位置计为 c 数组),我们只需要在c数组里面求一

UVa10653.Prince and Princess

题目连接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1576 13935381 10635 Prince and Princess Accepted C++ 0.095 2014-07-24 03:41:18 Prince and PrincessInput: Standard Input Output: Standard Output

UVa 10635 (LIS+二分) Prince and Princess

题目的本意是求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) 第一次