See LCS again

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

//无语了,什么都不想说。。。
#include <stdio.h>
#include <string.h>

int mark[100001], data[100001];

int binarySearch(int key, int n)     //二分查找大于等于且距离key最近的数的位置
{
    int left = 0, right = n, mid;
    while(left <= right)
    {
        mid = (left + right) / 2;
        if(mark[mid] >= key)
        {
            right = mid - 1;
        }
        else
        {
            left = mid + 1;
        }
    }
    return left;
}

/*void fun()       //测试二分查找是否正确
{
    int i, n, temp;
    scanf("%d", &n);
    for(i = 0; i < n; i++)
    {
        scanf("%d", &data[i]);
    }
    while(scanf("%d", &temp) != EOF)
    {
        printf("%d\n", binarySearch(temp, n-1));
    }
}
*/

int main()
{
   // fun();
    int n, m, i, temp, top, ans;
    while(~scanf("%d%d", &n, &m))
    {
        memset(mark, 0, sizeof(mark));
        top = 0;
        for(i = 1; i <= n; i++)
        {
            scanf("%d", &temp);
            mark[temp] = i;              //将原序列单调上升编号,并标记每个数
        }
        for(i = 1; i <= m; i++)
        {
            scanf("%d", &temp);
            if(mark[temp])
            {
                data[top++] = mark[temp];   //将两个序列中都有的数,以在第二个序列中的相对位置存入新序列
            }
        }
        ans = 0;
        mark[ans++] = data[0];
        for(i = 1; i < top; i++)       //判断单调最长子序列
        {
            if(data[i] > mark[ans-1])
            {
                mark[ans++] = data[i];
            }
            else
            {
                mark[binarySearch(data[i], ans-1)] = data[i];
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值