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);
  }
}
 
                    
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号