NYOJ 760

来源:互联网 发布:免费简历解析软件 编辑:程序博客网 时间:2024/04/28 10:57
See LCS again
时间限制:1000 ms  |  内存限制:65535 KB
难度:3
描述
There are A, B two sequences, the number of elements in the sequence is n、m;
Each element in the sequence are different and less than 100000.
Calculate the length of the longest common subsequence of A and B.
输入
The input has multicases.Each test case consists of three lines;
The first line consist two integers n, m (1 < = n, m < = 100000);
The second line with n integers, expressed sequence A;
The third line with m integers, expressed sequence B;
输出
For each set of test cases, output the length of the longest common subsequence of A and B, in a single line.
样例输入
5 4
1 2 6 5 4
1 3 5 4
样例输出

3

思路:

思路:DP好题,如果直接LCS递推求解的话,时间复杂度是O(n^2),接受不了。所以这样处理:先记录串A中每个数的位置,再在读入串B时记录串B中每个数在串A中的位置pos,然后就是在pos数组中求LIS的问题了,用经典的二分优化LIS,O(nlogn)的复杂度。



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


int v1,v2;
int p1[100005];
int pos[100005];
int que[100005];
int n,m;
int len;


int B_search(int val) {
    int l = 1,r = len + 1,mid;
    while(l < r) {
        mid = l + (r - l) / 2;
        if(que[mid] < val)
            l = mid + 1;
        else
            r = mid;
    }
    return l;
}


int main() {
    while(scanf("%d%d",&n,&m) == 2) {
        memset(p1,0,sizeof(p1));
        memset(pos,0,sizeof(pos));
        for(int i = 1; i <= n; ++i) {
            scanf("%d",&v1);
            p1[v1] = i;
        }
        for(int i = 1; i <= m; ++i) {
            scanf("%d",&v2);
            pos[i] = p1[v2];
        }
        len = 0;
        for(int i = 1; i <= m; ++i) {
            if(pos[i] == 0) continue;
            int index = B_search(pos[i]);
            que[index] = pos[i];
            if(index > len)
                ++len;
            //printf("plus:%d , len:%d\n",pos[i],len);
        }
        printf("%d\n",len);
    }
    return 0;
}
0 0
原创粉丝点击