您的位置:首页 > 其它

UVA 10635 Prince and Princess(最长上升子序列)

2015-07-17 22:43 316 查看
题意:有n*n的格子用1-n*n不同的数表示,第一个人输入p+1长度的数,第二个人输入q+1个不同的数,问他们最长公共子序列最长是多长。

分析:由于(0<=n<=250,n*n最大=250*250),用O(n^2)的算法是不能解决的,需要一种nlog(n)的算法。由于这里比较特殊,每个人输入的数都是不重复的,那么就把第一个人输入的数映射成1,2,3……,第二个人输入的数映射对应第一个人输入数的映射。这样,第一个人的映射是递增的,那么我只需要找到第二个人的映射的最长上升子序列的个数就是ans。

那么怎么求这个最长上升子序列呢?假设求1,4,6,3,5,7,最长上升子序列

dp[i]:表示长度为i,最小的那个数

①加入1,dp[1]=1;②加入4,dp[2]=4;③加入6,dp[3]=6;④加入3,dp[2]=3;⑤加入5,dp[3]=5;⑥加入7,dp[4]=7;

所以最终ans=4,这里,应为dp[]里存的数都是单调递增的,因此可以二分查找或lower_bound(加入的数)的id,更新dp[id]。

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <queue>
//http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82285#problem/E
#include <stack>
#include <vector>
#include <string>
#include <string.h>
#include <map>
#include <set>
using namespace std;
#define maxn 250*251
#define inff 1000000000
int a[maxn],b[maxn],dp[maxn];

int lower_bound(int aa[],int size,int k)//查找第一个>=k的数的id
{
    int l,r,mid;
    l=0;r=size-1;
    while(l <= r)
    {
      mid=(l+r)/2;
    if(aa[mid] >= k) r = mid - 1;
    else l = mid + 1;
  }
  return l;
}

int main()
{
    int t,k,n,num1,num2,i,m,tt=1;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&n,&num1,&num2);
        num1++;
        num2++;
        memset(a,-1,sizeof a);
        memset(b,-1,sizeof b);
        for(i=1;i<=num1;i++)
        {
            scanf("%d",&m);
            a[m]=i;//把第一个人的数映射成1,2,3……
        }
        k=1;
        for(i=1;i<=num2;i++)
        {
            scanf("%d",&m);
            if(a[m]!=-1)
            b[k++]=a[m];//第二个人输入的数,参照第一个人的映射,存下该数的映射
        }
        for(i=0;i<maxn;i++)
        {
            dp[i]=inff;
        }
        dp[0]=-1;//令dp[0]最小
        for(i=1;i<k;i++)
        {
            int j=lower_bound(dp,maxn-1,b[i]);
            dp[j]=b[i];
        }
        for(i=1;i<maxn;i++)
        {

            if(dp[i]==inff)
            {
                printf("Case %d: %d\n",tt++,i-1);
                break;
            }
        }

    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: