我们有一个火车站的交通信息,它的相似(到达,离开)时间对列车来到车站。像这样的东西T {[1,5],[2,4],[5,9],[3,10]}。然后,如何找到管理此流量所需的最少平台数。
答案 0 :(得分:2)
你需要找出最大重叠,对吧?这将为您提供最少数量的平台。只需初始化一个max(times)
元素等于0的数组,然后添加迭代遍历每个(arrival, departure)
间隔,为该区间中的数组的每个元素添加1。
然后,数组中任何元素的最大值是您需要的最小平台数。这适用于整数值区间。但是,该数组可能不是最快的方法。我会留给你的。
答案 1 :(得分:2)
在时间O(n log n)中存在一个解,其中n是给定的时间对的数量。 你必须回答这个问题:车站同时有多少列车? 为此,我们首先“标准化”时间值:确定所有时间段可能发生的有趣事件。为此,请对给定的所有到达和离开时间进行排序并消除重复。
在你的例子中,T = {[1,5],[2,4],[5,9],[3,10]},这会产生一个数组 A时间点[1,2,3,4,5,9,10],大小m = 7。
现在我们将每对的到达和离开时间转换为火车占用车站的时间段,即。即我们在数组A中找到时间值的索引(通过二进制搜索)。 E. g。对于[3,10],我们得到指数2和6,从零开始计算。
这就是容易的部分。使用索引对时间值进行排序和匹配,每个都以O(n log n)运行。现在我们必须计算每个指数,当时有多少列车站在车站。为了有效地做到这一点,我们使用了一个分段树。
该网站介绍了如何使用细分树: http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=lowestCommonAncestor#Segment_Trees
在下文中,您将在C ++中找到一个实现。我希望你能适应你的需求。如果有任何问题仍未解决,请随时提出。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
/** Given a number n and n pairs of arrival and departure times of trains,
* this program calculates the number of platforms needed in time O(n log n)
* If a train arrives exactly when another one leaves the station, you need
* two platforms. */
int main () {
int n;
cin >> n;
vector< pair<int,int> > T(n);
vector< int > A(2*n);
for (int i = 0; i < n; ++i) {
int arrival, departure;
cin >> arrival >> departure;
A[2*i] = arrival;
A[2*i+1] = departure;
T[i] = pair<int,int>(arrival, departure);
}
sort(A.begin(), A.end());
int m = unique(A.begin(), A.end()) - A.begin();
// for easy indexing, we need m to be a potency of 2
int pot2m = 1; while (pot2m < m) pot2m *= 2;
// Elements pot2m ... pot2m + m represent the bottom layer of the segment tree
vector< int > segtree(2*pot2m+1, 0);
// Now let's add everything up
for (int i = 0; i < n; ++i) {
int arrival = find(A.begin(), A.end(), T[i].first) - A.begin();
int departure = find(A.begin(), A.end(), T[i].second) - A.begin();
// Now increment
int a = arrival + pot2m;
int b = departure + pot2m + 1;
while (a < b) {
if (a % 2 == 1) ++segtree[a];
if (b % 2 == 1) ++segtree[b-1];
a = (a+1) / 2;
b = b / 2;
}
}
// Find the maximum value in the cells
int a = pot2m;
int b = pot2m + m;
while (a < b) {
int i, j;
for (i = a/2, j = a; j < b-1; ++i, j+=2) {
segtree[i] += max(segtree[j], segtree[j+1]);
}
if (j == b-1) segtree[i] += segtree[j]; // To handle odd borders
a /= 2;
b /= 2;
}
cout << "You need " << segtree[1] << " platforms." << endl;
return 0;
}
答案 2 :(得分:1)
我将继续讨论您的主题问题“如何解决这些问题以及哪种数据结构更适合处理?”
您已经举例说明了上述情况。这类问题称为优化问题(http://en.wikipedia.org/wiki/Optimization_problem)。
数据结构的选择将基于空间/时间权衡。因此,例如,可以通过使用简单数组或散列表或者图形来解决上述问题。真正重要的是有时可能需要指数运行时间来解决可能使它们成为NP-Complete / Hard的问题。假设您的例子中有n个平台和m个列车(其中n&amp; m非常大),那么就有可能发生组合爆炸。
此外,如果它导致指数时间并且说是NP完全/硬问题那么有几个启发式算法(例如,使用蚁群优化可以解决旅行推销员问题)也可以解决它,也许不是最优的一个。
在此上下文中算法比数据结构更重要。
答案 3 :(得分:1)
制作如下结构数组:(时间,IsArrival),其中IsArrival = +1抵达或-1离开
按时间键排序(考虑相同时间的情况)
初始化PlatformsNeeded = 0
遍历已排序的数组,将IsArrival添加到PlatformsNeeded,记住最大值