【HDU 1025】Constructing Roads In JGShining‘s Kingdom(二分法&最大上升子序列 详解)

Constructing Roads In JGShining's Kingdom

HDU 1025

题意描述:多实例,给出想要修的道路数量,以及这条路连通的穷富城市的编号。不会有某一个城市想连通两个城市的情况,穷富城市编号都是从1开始依次编号,不允许出现交叉道路的情况,求可以修的最多道路数量。

解题思路:道路情况有很多,我们需要舍去会造成道路交叉的某道路,利用一个数组find[],它含有的元素的个数是当前上升子序列的个数(除0),也就是find数组中是递增的。当有数据不加入find数组中,要更新前面的(用二分法找),此时不会影响结果,因为find数组中值(除0以外)的个数并没增加,要使修的道路数量len 增加,有两种可能:后面有元素大于find数组的最后一个元素就有(left>len),left代表的是find数组中更新的元素位置;被另一个元素连续更新,且更新到left>len,意思就是说:选出另一元素它能比当前元素构造的上升子序列要多。

易错分析:分开写road和roads的输出情况

AC:

#include<stdio.h>
#define N 500500
int e[N],find[N];
int main(void)
{
	int n,a,b,up,low,mid,len;
	int k=1;
	while(~scanf("%d",&n))
	{
		for(int i=1;i<=n;i++)
		{
			scanf("%d %d",&a,&b);//穷、富路
			e[a]=b;//第几个与第几个路相连,赋值给它 !题中要求没有出现多对1的情况 
		}
		find[1]=e[1];//先查到第一个可以连通了 
		len=1;
		for(int i=2;i<=n;i++)
		{
			low=1;
			up=len;
			while(low<=up)
			{
				mid=(low+up)/2;
				if(e[i]>find[mid])//如果第二个城市选的比第前一个城市远的话,互不影响 
					low=mid+1;//存进去 
				else
					up=mid-1;//不要这条 
			}
			find[low]=e[i];
			if(low>len)
				len++;
		}
		printf("Case %d:\n",k);
		if(len==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",len);
		k++; 
	}
	
	return 0;
 } 

猜你喜欢

转载自blog.csdn.net/m0_58245389/article/details/120463176