UVA 10635--Prince and Princess (lis)

题意:输入n,p,q,数据范围是n*n,p是第一个数组的长度,q是第二个数组的长度,求两个数组的最长相同子序列的长度。特别的是每个数组没有重复的的数据

思路:抓住没有重复数据的这一点、将第一个数组的数据与其下标一一对应,第二个数组的数据与第一个数组相同的数据保留,保留其在第一个数组内的下标,这样就是求最长子序列的问题了。lis算法即可。
感想:这个题重点就是每个数组内的数据没有重复的。然后转化成lis问题,感觉是个很有意思的题!

代码:

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
int T,n,m,p,q,num,x,lis[62505],top,a[62505],b[62505];
int main()
{
    scanf("%d",&T);
    map<int,int>ma;
    for(int  pp=1;pp<=T;pp++)
    {
        num=0;
        ma.clear();
        scanf("%d%d%d",&n,&p,&q);
        for(int i=0;i<=p;i++)
        {
            scanf("%d",&x);
            ma[x]=i;
        }
        top=0;
        lis[0]=-0x3f3f3f3f;
        for(int i=0;i<=q;i++)
        {
            scanf("%d",&a[i]);
            if(ma.find(a[i])!=ma.end())
            {
                b[++num]=ma[a[i]];
            }

        }
        for(int i=1;i<=num;i++)
        {
            if(b[i]>lis[top]) lis[++top]=b[i];
            else
            {
                int l=1,r=top,mid=-1;
                while(1)
                {
                    if((l+r)/2==mid) break;
                    mid=(l+r)/2;
                    if(lis[mid]>=b[i]) r=mid;
                    else l=mid;
                }
                lis[r]=b[i];
            }
           // cout<<top<<" "<<a<<endl;
        }
        printf("Case %d: %d\n",pp,top);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值