1.题目
L2-014 列车调度
分数 25
全屏浏览
切换布局
作者 陈越
单位 浙江大学
火车站的列车调度铁轨的结构如下图所示。
两端分别是一条入口(Entrance)轨道和一条出口(Exit)轨道,它们之间有N条平行的轨道。每趟列车从入口可以选择任意一条轨道进入,最后从出口离开。在图中有9趟列车,在入口处按照{8,4,2,5,3,9,1,6,7}的顺序排队等待进入。如果要求它们必须按序号递减的顺序从出口离开,则至少需要多少条平行铁轨用于调度?
输入格式:
输入第一行给出一个整数N (2 ≤ N ≤10
5
),下一行给出从1到N的整数序号的一个重排列。数字间以空格分隔。
输出格式:
在一行中输出可以将输入的列车按序号递减的顺序调离所需要的最少的铁轨条数。
输入样例:
9
8 4 2 5 3 9 1 6 7
输出样例:
4
2.分析
先看原理:
只要列车序号比轨道末尾的列车序号小就能排在其后面,例如铁轨上有8 4 ,则2号列车可以排到其后面。反之则需要另开一条铁轨。因此我们只需用一个数组记录每条铁轨的最小列车号就行了,数组的大小就是铁轨个数。
存储的数组其实是个递增序列,因为小的列车号都排在靠前的铁轨了。对于递增序列,我们用二分法就不会超时了。
3.代码
最开始用暴力查找,会时间超时。
#include<iostream>
using namespace std;
const int MAX=100000;
int main(){
int N,q[MAX],c=0,uns;
cin>>N;
for(int i=0;i<N;i++){
cin>>uns;
if(uns>q[c]) q[++c]=uns;
else{
for(int j=1;j<=c;j++){
if(q[j]>uns){
q[j]=uns;
break;
}
}
}
}
cout<<c<<endl;
}
换成二分查找就不会超时了。
#include<iostream>
using namespace std;
const int MAX=100000;
int main(){
int N,q[MAX],c=0,uns;
cin>>N;
for(int i=0;i<N;i++){
cin>>uns;
if(uns>q[c]) q[++c]=uns; //如果比铁轨里的最小值(数组的最大值)大,就增加一个铁轨
else{ //否则进行二分法替换铁轨的最小值
int l=1,r=c,t;
while(l<=r){
int mid=(l+r)>>1; //移位运算符相当于(l+r)/2
if(q[mid]>uns) t=mid,r=mid-1; //查找下标
else l=mid+1;
}
q[t]=uns;
}
}
cout<<c<<endl; //输出数组大小,即铁轨条数。
}