L2-014. 列车调度
火车站的列车调度铁轨的结构如下图所示。
![](https://www.patest.cn/upload/lp_o9wf01q8p76.jpg)
Figure
两端分别是一条入口(Entrance)轨道和一条出口(Exit)轨道,它们之间有N条平行的轨道。每趟列车从入口可以选择任意一条轨道进入,最后从出口离开。在图中有9趟列车,在入口处按照{8,4,2,5,3,9,1,6,7}的顺序排队等待进入。如果要求它们必须按序号递减的顺序从出口离开,则至少需要多少条平行铁轨用于调度?
输入格式:
输入第一行给出一个整数N (2 <= N <= 105),下一行给出从1到N的整数序号的一个重排列。数字间以空格分隔。
输出格式:
在一行中输出可以将输入的列车按序号递减的顺序调离所需要的最少的铁轨条数。
输入样例:9 8 4 2 5 3 9 1 6 7输出样例:
4
解题思路
题目大意是,一批列车,按递减顺序分车道,保证每个车道都是降序,这样才能按递减顺序离开。
题目要求输出”最少“的车道数,所以每个车都要选择车号大于自己且距离自己数值最近的车,且只需考虑每条车道上的最后一辆车的车号。
以样例数据为例,先排到9,得:
第一道:8-4-2-
第二道:5-3-
第三道:9-
然后考虑1,大于它且距离它最近的车是2,所以把它排在第一道,这样可以尽量少开辟新的车道。往后的都好办了,6排在9后面,7没有找到比它小的,所以另外开辟一条车道。
最终结果:
第一道:8-4-2-1-
第二道:5-3-
第三道:9-6-
第四道:7-
这样所有的车道都是按降序排列了,一共用了4条车道。
AC代码如下:
#include <iostream>
#include <stdio.h>
#include <math.h>
using namespace std;
int a[100001];//注意可能每辆车都找不到比它小的车,都开辟一条车道
int main()
{
int n;
scanf("%d",&n);
int len = 0;
while( n-- ){
int k;
scanf("%d",&k);
if( len==0 || k>a[len-1] ){//没有车或者车号比前面大,就另辟车道
a[len++] = k;
}
else{//车号比前面要小,就用二分法寻找最近车道(注意不能简单地排在当前车道后面,要找数最近的以减少可能占用的车道数)
int l=0,r=len-1;
while( l<r ){
int mid = (l+r)/2;
if( k<a[mid] ){
r = mid-1;
}
else{
l = mid+1;
}
}
a[l] = a[l]<k ? a[l]:k;
}
}
printf("%d\n",len);
return 0;
}