• uva10635


    题意求A、B两个序列的LCS。(A、B所含的元素分别是各不相同的)

    两个序列的长度最大是250*250,朴素的LCS的时间复杂度为O(nm),因此会超时。

    我们考虑这样一个操作。

    对于A={1,7,5,4,8,3,9},B={1,4,3,5,6,2,8,9}

    对于B中的每一个数,我们都找到其在A中出现的位置。(*没出现标为0)(因为这样不会给LIS带来贡献)

    则新的B数组={1,4,6,3,0,0,5,7}

    这么做的理由是:随着原来B的下标的增加,如果A中相应的数出现的位置也是这样增加的话,那么相同的数在A、B中都是在出现时间上是有序的。

    我们把这些在A、B中出现时间是有序的数都抽出来,自然是二者的CS,至于LCS,它相当于新的B数组的LIS。

    用一个hash实现求新的B数组。

    求LIS有nlogn的方法。

    如此降低了时间复杂度,利用的是元素不重复出现的这个优秀的性质。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 250 * 250 + 5, inf = 1e9;
    
    int kase, n, p, q;
    
    int num[maxn], a[maxn], g[maxn];
    
    int solve()
    {
        scanf("%d%d%d", &n, &p, &q);
        memset(num, 0, sizeof num);
        for (int i = 1; i <= p + 1; i++) 
        {
            int x;
            scanf("%d", &x);
            num[x] = i;
        }
        n = 0;
        for (int i = 1; i <= q + 1; i++)
        {
            int x;
            scanf("%d", &x);
            if (num[x]) a[++n] = num[x];
        }
    //    for (int i = 1; i <= q + 1; i++)
    //        printf("%d ", a[i]);
        for (int i = 1; i <= n; i++)
            g[i] = inf;
        int ans = 0;
        for (int i = 1; i <= n; i++)
        {
            int k = lower_bound(g + 1, g + 1 + i, a[i]) - g;
            ans = max(ans, k);
            g[k] = a[i];
        }
        return ans;
    }
    
        
    int main()
    {
    //    freopen("uva10635.in","r",stdin);
        scanf("%d", &kase);
        for (int i = 1; i <= kase; i++) 
        {
            int ans = solve();
            printf("Case %d: %d
    ", i, ans);
        }
        return 0;
    }
  • 相关阅读:
    asp.net mvc 从数据库中读取图片
    给折腾ramdisk的朋友们一点建议
    docker安装Jenkins和构建python容器
    docker笔记
    接口加密方式
    Dockerfile常用命令
    北斗七星小队团队展示
    固件程序设计实验内容1.4
    Myod实验 20181328祝维卿
    电子公文系统团队作业(四):描述设计
  • 原文地址:https://www.cnblogs.com/yohanlong/p/7757791.html
Copyright © 2020-2023  润新知