题目要求:
两端分别是一条入口(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
还是先说我的想法,一开始,想的太复杂了,其实没有那么难。找对思路,没有题是难的。
一开始我想到一种情况,就是序号最高的车占用一条轨道之后,他最先调离,所以这条轨道空了。和其他序号的车情况不一样,因为其他序号的车,进入轨道之后,就停了。但后来,证明我的这种想法完全多余。
因为,最高序号的车必定需要开拓一条轨道,它后面还有车的话,也就进入了这条轨道,和其他情况一样;后面没车的话,那也占用了一条轨道,也和其他车一样。QwQ。
唉,真是,想的越多,不如看优秀代码看得多。
思路:
我们需要尽量减少加轨道条数,也就是新的火车最好能到一条路线的末尾排着,而为了之后的顺序输出,一条轨道上后面的车需要比前面的编号小,这就产生了选择问题。
选择时,需要轨道中最后进入的车的序号大于插入的序号。这时候,比如轨道一:5号;轨道二:8号;需要插入一个4号,当然这两个都能插。但是如果插到8后面,那4和8之间的数(6、7)就只能再来一条轨道;插到5后面的话,6、7就可以到8后面。
所以,插入的时候,是插入到大于该序号且其中最小的序号后面的。。。不知道说没说明白。
代码如下:
#include<iostream>
using namespace std;
int main(){
int n;
cin>>n;
int root[n];
int len = 0;
int k;
while(n--){
cin>>k;
if(len == 0 || root[len-1] < k){
root[len++] = k;
}else{
//折半查找法
int one = 0,two = len-1;
while(one < two){
int mid = one + (two-one)/2;
if(root[mid] > k){
two = mid - 1;
}else{
one = mid + 1;
}
}
root[one] = k;
/* //普通 顺序 查找,因为排列是按顺序的,所以也可以按顺序查找,但是当数据过多时,容易超时
for(int i=0;i<=len-1;i++){
if(root[i] > k){
root[i] = k;
break;
}
}
*/
}
}
cout<<len;
return 0;
}
其中有一段折半查找法,是因为(2 ≤ N ≤10 5 ),数据过多时,且排好序时,这种方法优选。另一种按顺序查找的会超时。
好了,以上就是今天的全部内容,咱们下期再见。
一个集坚强与自信于一身的菇凉。