L2-014 列车调度 贪心 二分查找
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
作者:陈越
单位:浙江大学
代码长度限制:16 KB
时间限制:300 ms
内存限制:64 MB
PZ's Solution
1.考虑对于当前编号为\(x\)的列车;
2.若对于某一轨道末尾上的编号为\(q_i\)的列车,如果\(q_i>x\),则当前编号的车辆就可以排在此轨道的末尾;
3.显然,当\(q_i\)越接近\(x\),答案自然也就越优;
4.创建一个数组\(Q\),存储所有轨道末尾列车的编号,观察2.3.条件,可以发现,\(Q\)实际上为一个升序数组,则可以考虑二分查找一个最接近\(x\)的\(q_i\);
5.特殊地,如果不存在\(q_i>x\),则需要新开一条轨道让编号为\(x\)的列车通过;
6.数组\(Q\)的长度即为答案;
PZ.cpp
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,q[100005],ans;
int main(){
scanf("%d",&n);
for(int x,i=1;i<=n;++i){
scanf("%d",&x);
if(q[ans]<x) q[++ans]=x;
else {
int l=1,r=ans,res;
while(l<=r){
int mid=l+r>>1;
if(q[mid]>=x) res=mid,r=mid-1;
else l=mid+1;
}
q[res]=x;
}
}
printf("%d",ans);
return 0;
}