火车站的列车调度铁轨的结构如下图所示。
![](http://nos.patest.cn/lp_o9wf01q8p76.jpg)
Figure
两端分别是一条入口(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
思路:因为要保证火车能按序号递减出列,所以要保证每条轨道里“序号大者优先”(即序号大的火车排在序号小的或者的前面)
如图,按箭头顺序遍历每一个数,如果当前数大于任何一条轨道的末尾火车序号,则它只能“另起炉灶”,而如果不是,则找到第一条末尾火车序号大于等于它的轨道,将它放在这条轨道的最后。
AC代码:
#include <iostream> #include<cstdio> using namespace std; int a[100010];//用a[i]表示第i条轨道的末尾火车序号,则序列a必定是递增的 int main() { int n; scanf("%d",&n); int len=0; while(n--){ int tmp; scanf("%d",&tmp); if(len==0||a[len]<tmp) a[++len]=tmp; else{ int l=1,r=len; while(l<=r){//序列a递增,可用二分查找序列a中第一个大于等于tmp的元素位置 int mid=(l+r)/2; if(a[mid]>tmp) r=mid-1; else l=mid+1; } a[l]=tmp; } } printf("%d\n",len);//最终序列a的长度就是最少所需轨道数 return 0; }
此题可用STL中的set(集合)代替上述a[100010],以对容器set的操作代替对数组a的操作
set容器中元素互不相同,其中元素自动按升序排序
set的基本操作:
set<int > s;//定义set容器s
s.clear();//清空s中所有元素
s.empty();//判断s是否为空
s.size();//得到s的元素个数
s.insert(x);//向s中插入元素x
s.erase(it);//删除s中迭代器it所指向元素
s.lower_bound(x);//查找s中第一个大于等于x的值,返回其迭代器
AC代码:
#include <iostream> #include<cstdio> #include<set> using namespace std; set<int >s; int main() { int n; scanf("%d",&n); while(n--){ int tmp; scanf("%d",&tmp); if(s.empty()) s.insert(tmp); else{ set<int >::iterator it; it=s.lower_bound(tmp); if(it==s.end()) s.insert(tmp); else { s.erase(it); s.insert(tmp); } } } printf("%d\n",s.size()); return 0; }