火车站的列车调度铁轨的结构如下图所示。
两端分别是一条入口(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
所以只需要四个调度队列就可以了。
实现:
在实现过程中,我最开始想的是初始化一个二维数组;即每个二维数组去模拟我们的各个用于调度的轨道。即每一次都对每一个已经插入数值的轨道进行判断,判断当前插入的值能否插入该轨道,如果每一个已经插入数值的轨道都无法插入当前的值,则新开辟一个轨道。但是观察以上的四个下降序列,我发现只需要判断每个序列中的最小的那一个元素与当前元素进行比较,则可以判断当前值是否能够插入队列。
所以我们只需要使用一个容器用于储存当前已存在的每个序列的最小值即可。随后插入数据,使用lower_bound()方法来找到比当前数据大的值的位置,插入该位置。(因为一个序列中小数据要插入大数据后面,所以插入时我们替换该位置的值就行了,表示替换一个序列的最小元素。)
以输入样例为例:
首先我们初始化一个 容器,使他的值都为无限大(用999表示无限大):
999 999 999 ......
随后插入8,此时是插入第一个位置,序列变为:
8 999 999 999......
随后插入4,4是可以和8在同一个轨道了,所以此时使用4替换8(表示4为第一个轨道中的最小元素):
4 999 999 999......
随后2和插入4的过程一样:
2 999 999 999......
随后插入5,当前仅开辟了一条轨道,该轨道的最小元素为2(小于5),所以需要新开辟一条轨道,5插入到第二个位置,表示第二条轨道的最小元素为5:
2 5 999 999 999......
插入3,与2替换4同理,用3替换5:
2 3 999 999 999......
插入9,新开辟轨道:
2 3 9 999 999 999......
插入1,替换第一条轨道的最小元素:
1 3 9 999 999 999......
插入6,替换第三轨道的9:
1 3 6 999 999 999......
插入7,没有比7更小的值,新开辟一条轨道
1 3 6 7 999 999 999......
插入结束,当前开辟轨道数4条,与答案对应.......
具体代码:
代码还是比较简单的,主要是要理解题意,分数还是很容易拿到的。
#include<bits/stdc++.h>
using namespace std;
int N[100005];
#define MAX 0x3f3f3f3f //定义MAX为无穷大的常量
int main()
{
int n;
cin >> n;
memset(N, MAX, sizeof(N)); //初始化N序列都为无穷大的常量
for (int i = 0; i < n; i++)
{
int m, t;
cin >> m;
t = lower_bound(N, N + n, m) - N; //找到比当前插入元素大的元素位置
N[t] = m; //插入当前位置
}
cout << lower_bound(N, N + n, MAX) - N; //输出当前第一个无穷大的位置,即轨道数
return 0;
}