一、题目描述
两端分别是一条入口(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
二、解题思路
根据输入样例,我们容易得出
8 4 2 1
5 3
9 6
7
这四条轨道
也就是说,将每一个数x插到之前已按升序序列中使得y>x 且y最小,求序列的总长度
也就是说我们只要将序列中最新插入的那个序号作为序列的最新大小
我们只要保证插入的时候,是按照升序插入,那么题目就很容易做出来了
为什么要是升序呢?便于比较、增加与查找
三、代码如下
#include<iostream>
using namespace std;
#define MAX 100010
int Entrance[MAX]; //输入的序号
int road[MAX]={0}; //每个轨道
int all=0; //总轨道数
//二分查找
int Find(int x)
{
int low=0,high=all-1;
while(low<=high)
{
int mid=(low+high)/2;
if(x>=road[mid])
low=mid+1;
else
high=mid-1;
}
return low;
}
void Slove(int n)
{
int i;
//如果新来的数n大于当前road中最大数,则添加至road末尾
if(road[all-1]<n)
{
road[all++]=n;
return;
}
//查找当前road中大于n中的最小数的下标
i=Find(n);
road[i]=n;
}
int main()
{
int i;
int N;
cin>>N;
for(i=0;i<N;i++)
{
cin>>Entrance[i];
if(i==0)
road[all++]=Entrance[i];
else
Slove(Entrance[i]);
}
cout<<all<<endl;
return 0;
}