火车站的列车调度铁轨的结构如下图所示。
两端分别是一条入口(Entrance)轨道和一条出口(Exit)轨道,它们之间有N
条平行的轨道。每趟列车从入口可以选择任意一条轨道进入,最后从出口离开。在图中有9趟列车,在入口处按照{8,4,2,5,3,9,1,6,7}的顺序排队等待进入。如果要求它们必须按序号递减的顺序从出口离开,则至少需要多少条平行铁轨用于调度?
输入格式:
输入第一行给出一个整数N
(2 ≤ N
≤),下一行给出从1到N
的整数序号的一个重排列。数字间以空格分隔。
输出格式:
在一行中输出可以将输入的列车按序号递减的顺序调离所需要的最少的铁轨条数。
输入样例:
9
8 4 2 5 3 9 1 6 7
输出样例:
4
比较巧的一道题,感觉放在ACM比赛上作为一道签到题非常合适,但是,还是稍微听队友解释了下才做出来的。然后就是关于lower_bound 的应用,之前还不会用,现在会用了。
题目意思就是需要我们先把列车放到轨道中,必须是按输入的顺序,最后通过选择不同轨道的第一个放入最终的轨道,使得最终的结果是递增的。感觉这个多个轨道就像是多个队列,先进先出。然而这个题和队列没有关系。
那么,我们就模拟这个情况嘛, 一开始,让列车进一个轨道,下一个列车,如果比上一个小,还是使用同一个轨道,如果大,就新开一个轨道。这是最基本的思想,那么更具体的说,在下一个数更小的这种情况,不能随便选一个轨道,随便选可能会影响后面的,这时候就要用到贪心的思想了,就是每次找数值最相近的轨道, 大家可以在纸上模拟一下案例,就会发现,只要是有点智商的人都会这样选,很简单的道理。
至于怎么实现,每次找最接近的时候可以用二分,或者直接用lower_bound,很有用的一个函数,找到最相近的。
这个题的轨道的值一定是递增的,大家可以想想为什么,多在纸上画画。
这个题绝对不难,但是能快速想到二分,我绝对还是挺考脑力的。
代码:
#include<iostream>
using namespace std;
#include<cstdio>
#include<cstring>
#include<stack>
#include<cstdlib>
#include<queue>
#include<algorithm>
int n;
const int maxn = 1e6+2;
int a[maxn];
int main()
{
while( scanf("%d",&n) == 1 )
{
memset(a,0,sizeof(a));
int cnt = 1;
for( int i = 1 ; i <= n ; i++ )
{
int item;
scanf("%d",&item);
if( i == 1 )
a[1] = item;
else if( item > a[cnt] )
a[++cnt] = item;
else
{
int t = lower_bound(a+1,a+cnt,item)-a;
a[t] = item;
//printf("%d\n",t);
}
}
printf("%d\n",cnt);
}
return 0;
}