UVA 10635 Prince and Princess【LCS 問題轉換爲 LIS】

題目鏈接:

http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=19051

題意:

有兩個長度分別爲p+1q+1 的由1n2 之前的整數組成的序列,每個序列的元素各不相等,兩個序列第一個元素均爲1。求兩個序列的最長公共子序列。

分析:

LCS 的複雜度爲O(pq) ,這題p,q 最大爲250 * 250,必T無疑。
注意題目說的每個序列的元素各不相等,那麼就能保證我們可以把序列A的元素用1p+1 重新進行賦值,把B中元素根據A的賦值找到對應的標號,用0表示沒有出現過,那麼問題就可以轉化爲LIS 啦,時間複雜度O(nlogn) ,可以過了。
有關LIS 的內容這裏有一個http://blog.csdn.net/yukizzz/article/details/50620631

代碼:

/*************************************************************************
    > File Name: 10635.cpp
    > Author: jiangyuzhu
    > Mail: [email protected] 
    > Created Time: Sat 18 Jun 2016 08:57:43 PM CST
 ************************************************************************/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<stack>
using namespace std;
#define sa(n) scanf("%d", &(n));
typedef pair<int, int>p;
const int maxn = 250 + 5, mod = 1e9 + 7, oo = 0x3f3f3f3f;
int a[maxn * maxn], b[maxn * maxn], nb[maxn * maxn];
int pos[maxn * maxn];
int dp[maxn * maxn];
int main (void)
{
    int t;sa(t);    
    for(int kas = 1; kas <= t; kas++){
        int n, p, q;sa(n);sa(p);sa(q);
        memset(pos, 0, sizeof(pos));
        for(int i = 0; i <= p; i++){
            sa(a[i]);
            pos[a[i]] = i;
        }
        memset(nb, 0, sizeof(nb));
        for(int i = 0; i <= q; i++){
            sa(b[i]);
            nb[i] = pos[b[i]];
        }
        memset(dp, 0x3f, sizeof(dp));
        for(int i = 0; i <= q; i++){
            *lower_bound(dp, dp + q + 1, nb[i]) = nb[i];
        }
        int ans = lower_bound(dp, dp + q + 1, oo) - dp;
        printf("Case %d: %d\n", kas, ans);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章