zoukankan      html  css  js  c++  java
  • 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
    ", i_case, (int )(lower_bound(dp, dp+k, INF) - dp));
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    Java 测试代码模板
    git 保存用户名和密码
    git 高级命令
    git 最常用命令
    git 冲突解决
    git diff命令
    nginx静态服务器的配置
    使用SFTP工具下载文件
    git log 格式化输出
    9-angular.fromJson
  • 原文地址:https://www.cnblogs.com/xuelanghu/p/4562387.html
Copyright © 2011-2022 走看看