CCCC团体程序设计天梯赛 L2-014 列车调度

记录天梯赛题目合集 跳转查看

题目链接

题目描述

火车站的列车调度铁轨的结构如下图所示。

两端分别是一条入口(Entrance)轨道和一条出口(Exit)轨道,它们之间有N条平行的轨道。每趟列车从入口可以选择任意一条轨道进入,最后从出口离开。在图中有9趟列车,在入口处按照{8,4,2,5,3,9,1,6,7}的顺序排队等待进入。如果要求它们必须按序号递减的顺序从出口离开,则至少需要多少条平行铁轨用于调度?

题目解析

首先分析一下题目给出的样例是如何做到用4个通道完成重排顺序的。

原顺序为{8,4,2,5,3,9,1,6,7},8 第一个进入,自然放入第一个通道,接下来的{4,2},保持顺序递减,也可以跟在 8 后面进入第一个通道。但到了 5 ,它如果也进入第一个通道,那么出去时无论如何也会在{4,2}后面,做不到顺序递减,所以 5 应进入新的通道,接下来是 3 ,它同理也是不能进入第一个通道的,但它比 5 小可以进入第二个通道。到了 9 和 5 是同理,两个通道都不能进入,所以它要进入第三个通道。如此类推,第一个通道{8,4,2,1},第二个通道{5,3},第三个通道{9,6},第四个通道{7},这样每个通道内都是递减,在出去时,第三个通道的 9 第一个出去,紧接着是第一个通道的8,第四个通道的7,这样就可以做到出去顺序是递减的。

这时候,可以观察到规律了,也就是新的元素,如果可以进入存在的通道中使内部保持递减,那么就进入该通道。但如果真的开数组模拟通道,意味着每次都需要扫描一遍所有通道,在最坏情况下时间复杂度到达 \(n^2\),显然不行。

继续观察上面的过程,可以发现,后面的数之所以不能进入第一个通道了,是因为第一个通道的最后一个数比较小,而要最佳情况,按原顺序最长能得到长度为4的上升序列,如{2,3,6,7},这四个元素只能分属不同的通道,意味着最少都要4个通道。

所以,问题转向求最长的上升序列长度,这就是经典DP问题了,使用二分优化,时间复杂度为\(O(nlogn)\)

代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <stack>

using namespace std;

typedef long long ll;
typedef pair<int, int> PII;

const ll inf = 1e18;
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 10;

int n;

void solve()
{
	cin >> n;
	vector<int> a(n);
	for (int i = 0; i < n; i ++) cin >> a[i];
	
	vector<int> dp;
	for (int i = 0; i < n; i ++) {
		int pos = lower_bound(dp.begin(), dp.end(), a[i]) - dp.begin();
		if (pos == dp.size()) dp.emplace_back(a[i]);
		else dp[pos] = a[i];
	}
	cout << dp.size();
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr), cout.tie(nullptr);
	
	int T = 1;
//	cin >> T;
	while (T --) solve();
	return 0;
}
posted @ 2025-09-01 12:13  Natural_TLP  阅读(22)  评论(0)    收藏  举报