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号