zoukankan      html  css  js  c++  java
  • UVA 10635 Prince and Princess

    有两个长度可能是250*250的数字串,串内元素两两不同,求最长公共子串。

    常规的O(n^2)解法不论是时间或空间都无法解决,办法是转化成求最长上升子序列。

    假设是有串1和串2。先给串1的元素按输入顺序来一个映射,称为映射1。比如说

    1 7 5 4 8 3 9 映射成 0 1 2 3 4 5 6。那么s1[7]=1,s1[9]=6。映射完成之后处理第二个字符串。

    第二个字符串按映射1再来一次映射。比如 1 4 3 5 6 2 8 9 映射成,0 3 5 2 4 6 -1 -1,其中-1说明串2的该元素不在串1中出现,必然不可能算入最长公共子串中,于是对于-1的元素选择删掉,得到一个新的序列:0 3 5 2 4 6。这个新序列的意义是:串2的元素按串1元素的位置映射出的序列。那么这个新序列的最长上升子序列就是解。求最长上升子序列有一个利用二分的O(nlogn)解法,可以自行搜索。

    代码:

    #include <iostream>
    #include <bits/stdc++.h>
    using namespace std;
    
    #define ll long long
    #define mst(a,b) memset(a,b,sizeof(a))
    #define rep(i,a,b) for(ll i=(a);i<(b);++i)
    #define scf(n) scanf("%d", &(n));
    #define lb lower_bound
    const double eps = 1e-8, PI = acos(-1.0f);
    const int inf = 0x3f3f3f3f, maxN = 250 + 5;
    int N, P, Q, T;
    int s1[maxN * maxN], s2[maxN * maxN], dp[maxN * maxN];
    
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("data.in", "r", stdin);
    #endif
        scf(T);
        rep(cas, 1, T + 1) {
            scanf("%d%d%d", &N, &P, &Q);
            ++P; ++Q;
            int t;
            mst(s1, -1);
            mst(s2, -1);
            rep(i, 0, P) {
                scf(t);
                s1[t] = i;
            }
            int cnt = 0;
            rep(i, 0, Q) {
                scf(t);
                if (s1[t] != -1)
                    s2[cnt++] = s1[t];
            }
    
            mst(dp, inf);
            rep(i, 0, cnt) {
                *lb(dp, dp + cnt, s2[i]) = s2[i];
            }
            printf("Case %lld: %ld
    ", cas, lb(dp, dp + cnt, inf) - dp);
        }
        return 0;
    }
  • 相关阅读:
    js获取url参数
    Ueditor百度编辑器中的 setContent()方法的使用
    js防止sql注入的参数过滤
    父级元素点击,遮盖了子元素的点击
    input onchange事件
    jq选择子元素
    nodejs mysql 执行多条sql语句
    java.util.ConcurrentModificationException
    Group by与having理解
    ibatis配置xml文件中CDATA的用法
  • 原文地址:https://www.cnblogs.com/Rosebud/p/9083686.html
Copyright © 2011-2022 走看看