Constructing Roads In JGShining's Kingdom(HDOJ1025)

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1025 求最长上升子序列的长度

解题思路:用二分查找法

手工模拟:比如求序列5 6 7 1 2 8 3的最长上升子序列的长度。

             data【】数组存储原始数据,dp【】数组存储最长递增序列,max表示目前递增序列的最大长度

             data【1】=5                   初始化:dp【0】=-1,dp【1】=data【1】=5,max=1。从索引为2处开始查找比较:

             data【2】=6  第一次查找比较后dp【0】=-1,dp【1】=5,dp【2】=6,max=2;      

             data【3】=7  第二次查找比较后dp【0】=-1,dp【1】=5,dp【2】=6,dp【3】=7,max=3;              

             data【4】=1  第三次查找比较后dp【0】=-1,dp【1】=1,dp【2】=6,dp【3】=7,max=3;               

             data【5】=2  第四次查找比较后dp【0】=-1,dp【1】=1,dp【2】=2,dp【3】=7,max=3;              

             data【6】=8  第五次查找比较后dp【0】=-1,dp【1】=1,dp【2】=2,dp【3】=7,dp【3】=8,max=4;  

             data【7】=3  第六次查找比较后dp【0】=-1,dp【1】=1,dp【2】=2,dp【3】=7,dp【3】=3,max=4;

代码:

#include <stdio.h>
#include<memory.h>
#include<algorithm>
int data[500000];
int dp[500000];
int main()
{
  int num,count=0,max,l,r,mid;
  while(~scanf("%d",&num))
  {
    count++;
    memset(data,0,sizeof(data));
    max=1;
    int p,r;
     for(int i=0;i<num;i++)
     {
        scanf("%d%d",&p,&r);
        data[p]=r;
     }
     dp[0]=-1;
     dp[1]=data[1];
     for(int i=2;i<=num;i++)
     {
         l=0;
         r=max;
         while(l<=r)
         {
            mid=(l+r)/2;
            if(data[i]>dp[mid])
                l=mid+1;
            else
                r=mid-1;
         }
         dp[l]=data[i];
         if(l>max)
             max++;
     }
     if(max==1)
      printf("Case %d:\nMy king, at most 1 road can be built.\n\n",count);
     else
      printf("Case %d:\nMy king, at most %d roads can be built.\n\n",count,max);
  }
}

 

posted @ 2013-04-10 23:44  supersnow0622  Views(102)  Comments(0)    收藏  举报