题目大意:一对平行线,每条线上有n个城市,线上的城市两两建立道路,共n条,问最多有多少条不相交的道路。
神奇的动态规划。
主要思路如下:
1.用len表示最大可连接数,随着输入的增加,len增加,num[1]表示对于第一次输入rich城市编号
2.如果f[n]>num[len],num[++len]=f[n],即把rich城市编号赋值给数组num下一个。
3.如果f[n]<num[len],就在递增的num数组中找到一个位置,如对于数组值为0,1,4,7时f[n]=3,f[n]>1,f[n]<4,将4替换,变为0,1,3,7.(这里用二分法实现)
#include <stdio.h>
#include <string.h>
int f[500010];//表示城市之间的连接情况,f[n]下标n表示poor城市编号n,其值表示rich城市。
int num[500010];//从num[1]开始保存最小f[n]的值
int main()
{
int n,i,t=1;
int a,b;
int len;
int low,up,mid;
while(scanf("%d",&n)!=EOF)
{
len=1;
memset(num,0,sizeof(num));
f[0]=0;
for(i=1;i<=n;i++)
{
scanf("%d %d",&a,&b);
f[a]=b;
}
num[len]=f[1];
for(i=2;i<=n;i++)
{
if(f[i]>num[len])
{
num[++len]=f[i];
continue;
}//对应2步骤
low=1;up=len;
while(low<=up)//这里不用二分法会超时
{
mid=(low+up)/2;
if(f[i]>num[mid])
low=mid+1;
else
up=mid-1;
}
num[low]=f[i];//对应3步骤
}
printf("Case %d:\n",t++);//注意输出格式
if(len==1)
printf("My king, at most 1 road can be built.\n");
else
printf("My king, at most %d roads can be built.\n",len);
printf("\n");
}
return 0;
}