题目来源:L2-014 列车调度
火车站的列车调度铁轨的结构如下图所示。
两端分别是一条入口(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
思路:
没看n是1e5,上来就交了一发优先队列加vector,tle了两个样例。
其实这题应该是LIS的变形,求的是最少下降子序列,也就是求最长上升子序列。
代码:
#include <iostream>
#include <bits/stdc++.h>
#include <cstring>
#include <stdio.h>
#include <algorithm>
#include <queue>
using namespace std;
const int mod = 1e8+7;
int n, m, x, y;
int a[100050];
int pos[100050];
string read() {
string s = "";
int ch = getchar();
while (ch == '\n') ch = getchar();
while (ch != '\n') s += ch, ch = getchar();
return s;
}
int Find(int x, int num) {
int l = 1, r = num;
while (l < r) {
int mid = (l+r)>>1;
if (pos[mid] < x)
l = mid+1;
else
r = mid;
}
return l;
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
}
pos[0] = -1;
pos[1] = a[1];
int cnt = 1;
for (int i = 2; i <= n; i++) {
if (a[i] > pos[cnt]) {
cnt++;
pos[cnt] = a[i];
}
else {
int po = Find(a[i], cnt);
pos[po] = a[i];
}
}
printf("%d\n", cnt);
return 0;
}