n*logn最长上升序列

hdu1025        

2分查找+DP;

View Code
#include<stdio.h>
int a[500001],b[500001];
int main()
{
    int u=1,n,x,y,i,j;
    while(scanf("%d",&n)!=EOF)
    {
        for(i=1;i<=n;i++)
        {
            scanf("%d%d",&x,&y);
            a[x]=y;
        }
        int len=1;b[1]=a[1];
        for(i=1;i<=n;i++)           //2分查找
        {
           int low=1,high=len,mid;
           while(low<=high)
           {
               mid=(low+high)/2;
               if(b[mid]>=a[i])high=mid-1;
               else low=mid+1;
           }
           b[low] = a[i];
           if(low>len) len++;
        }
        printf("Case %d:\n",u++);
        if(len==1)printf("My king, at most %d road can be built.\n",len);
        else printf("My king, at most %d roads can be built.\n",len);
        printf("\n");
    }
}

NOIP1999

 分别求一组数的最长不上升序列和最长上升序列

2分查找+DP

View Code
#include<stdio.h>
#define maxn 30001
int a[maxn],b[maxn],n,len1,len2;
int search1(int temp)
{
    int mid,high=len1,low=1;
    while(low<=high)
    {
        mid=(low+high)/2;
        if(temp>a[mid])high=mid-1;
        else low=mid+1;
    }
    if(low>len1)len1++;
    return low;
}
int search2(int temp)
{
    int mid,high=len2,low=1;
    while(low<=high)
    {
        mid=(low+high)/2;
        if(temp<=b[mid])high=mid-1;
        else low=mid+1;
    }
    if(low>len2)len2++;
    return low;
}
int main()
{
    int i,temp;
    while(scanf("%d",&n)!=EOF)
    {
       scanf("%d",&temp);
       a[1]=b[1]=temp;n-=1;len1=len2=1;
       while(n--)
       {
           scanf("%d",&temp);
           int k=search1(temp);a[k]=temp;
           k=search2(temp);b[k]=temp;
       }
       printf("%d\n%d\n",len1,len2);
    }
    return 0;
}

 

posted @ 2012-05-26 22:21  To be an ACMan  Views(480)  Comments(0)    收藏  举报