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数组里面求一个上升的子序列。而LIS是可以O(nlongn)做的。

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

const int INF = 999999999;

int a[62505];
int s[62505];
int dp[62505];

int main () {
    int T;
    cin >> T;
    for (int i_case = 1; i_case <= T; i_case++) {
        int n, _a, _b;
        cin >> n >> _a >> _b;

        memset(a, -1, sizeof a);
        for (int j=0; j<=_a; j++) {
            int tmp;
            scanf("%d", &tmp);
            a[tmp] = j;
        }

        for (int i=0; i<=_b; i++) {
            int tmp;
            scanf("%d", &tmp);
            s[i] = a[tmp];
        }

        int k=0;
        for (int i=0; i<=_b; i++) {
            if (s[i] == -1) continue;
            s[k++] = s[i];
        }

        fill (dp, dp + k, INF);
        for (int i=0; i < k; i++) {
            *lower_bound(dp, dp+k, s[i]) = s[i];
        }
        printf("Case %d: %d\n", i_case, (int )(lower_bound(dp, dp+k, INF) - dp));
    }

    return 0;
}

时间: 2024-12-16 03:13:07

UVA 10635 Prince and Princess 最长公共子序列(nlongn)的相关文章

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

UVA - 10635 —— Prince and Princess

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

UVA 10100- Longest Match(dp之最长公共子序列)

题目地址:UVA 10100 题意:求两组字符串中最大的按顺序出现的相同单词数目. 思路:将字串中的连续的字母认作一个单词,依次计算出两个字符串中的单词,其中第1个字符串的单词序列为t1.word[1]-..t1.word[n],第2个字符串的单词序列为t2.word[1]-..t2.word[m].然后将每个单词当成一个字符,使用LCS算法计算出两个字符串的最长公共子序列,该序列的长度就是最长匹配. #include <stdio.h> #include <math.h> #in

uva 11151 Longest Palindrome (最长公共子序列)

uva 11151 Longest Palindrome A palindrome is a string that reads the same from the left as it does from the right. For example, I, GAG and MADAM are palindromes, but ADAM is not. Here, we consider also the empty string as a palindrome. From any non-p

UVA 111 History Grading (最长公共子序列)

History Grading Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Background Many problems in Computer Science involve maximizing some measure according to constraints. Consider a history exam in which students are asked to put s

UVa 10066 Twin Towers (DP 最长公共子序列)

题意  求两串数字最长公共子序列的长度 裸的lcs没啥说的 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=105; int a[maxn],b[maxn],d[maxn][maxn],na,nb; void lcs() { memset(d,0,sizeof(d)); for(int i=1; i<=na; ++i) for(in

算法竞赛与入门经典---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 (LCS转化为LIS)

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