HDU 1025 最长递增子序列问题

参考:http://www.cnblogs.com/lonelycatcher/archive/2011/07/28/2119123.html
//最长递增自序列,吉林大学模板
#include<iostream>
#include<stdio.h>
#include<cstdlib>
#include<string.h>
using namespace std;
int N,ans;
int a[500010];
int f[500010];
int d[500010];//d[i]表示以结尾的最长递增子序列长度,当然,这道题中,数组d可以用不到的
int bsearch(const int* f,int size,const int& a)
{
    int left=0;
    int right=size-1;
    while(left<=right)
    {
        int mid=(left+right)>>1;
        if(a>f[mid-1]&&a<=f[mid])return mid;
        else if(a<f[mid])right=mid-1;
        else left=mid+1;
    }
}
int LIS(const int* a,const int& n)
{
    int i,j,size=1;
    f[0]=a[0];d[0]=1;//d[i]表示以i结尾的最长上升子序列的长度,f[i]表示d 值为i 时候的最小a值
    for(i=1;i<n;i++)
    {
        if(a[i]<=f[0])
        {
            j=0;
        }
        else if(a[i]>f[size-1])j=size++;
        else j=bsearch(f,size,a[i]);
        f[j]=a[i];
        d[i]=j+1;
    }
    return size;
}
int main()
{
    int i,cases=0;
    while(scanf("%d",&N)!=EOF)
    {
        memset(f,0,sizeof(f));
        memset(d,0,sizeof(d));
        cases++;
        for(i=0;i<N;i++)
        {
            int from,to;
            scanf("%d %d",&from,&to);
            a[from-1]=to-1;
        }
        ans=LIS(a,N);
        printf("Case %d:\n",cases);
        if(ans==1)
        {
            printf("My king, at most 1 road can be built.\n\n");
        }
        else
        printf("My king, at most %d roads can be built.\n\n",ans);
    }
    return 0;
}

posted on 2011-07-28 10:20  lonelycatcher  阅读(1520)  评论(0编辑  收藏  举报

导航