【问题标题】:How to solve problems involving overlapping pairs and which data structure to use如何解决涉及重叠对的问题以及使用哪种数据结构
【发布时间】:2012-02-27 06:11:48
【问题描述】:

有一个火车站,我们有它的交通信息,它就像(到达,离开)时间对访问车站的火车。像这样的东西 T{ [1,5],[2,4],[5,9],[3,10] }。然后如何找到管理此流量所需的最少平台数。

【问题讨论】:

  • 这是作业吗?然后你应该这样标记它。

标签: c algorithm optimization data-structures


【解决方案1】:

您需要找出最大重叠,对吗?这将为您提供最少数量的平台。只需使用等于 0 的 max(times) 元素初始化一个数组,然后添加然后迭代每个 (arrival, departure) 区间,将区间中的每个数组元素加 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。

    现在我们将每对的到达和离开时间转换为火车占用车站的时间段,即。 e.我们在数组 A 中找到时间值的索引(通过二进制搜索)。例如。对于 [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;
    }
    

    【讨论】:

      【解决方案3】:

      我会回答你的主题行问题“如何解决这些问题以及哪种数据结构更好处理?”

      您已经为上述内容提供了一个示例。这类问题称为优化问题 (http://en.wikipedia.org/wiki/Optimization_problem)。

      数据结构的选择将基于空间/时间的权衡。因此,例如,可以通过使用简单的数组或哈希表或图形来解决上述问题。真正重要的是,有时解决此类问题可能需要指数级的运行时间,这可能会使它们成为 NP-Complete/Hard。假设考虑到您的示例,您有 n 个平台和 m 个火车(其中 n 和 m 非常大),那么就有可能发生组合爆炸。

      另外,如果它导致指数时间并且说是一个 NP-Complete/Hard 问题,那么也有几种启发式算法(例如,可以使用 Ant Colony Optimization 解决旅行推销员问题)来解决它,也许不是最理想的。

      在这种情况下,算法比数据结构更重要。

      【讨论】:

        【解决方案4】:

        创建一个这样的结构数组:(Time, IsArrival),其中 IsArrival = +1 表示到达或 -1 表示离开

        按时间键排序(考虑时间相等的情况)

        初始化 PlatformsNeeded = 0

        遍历排序数组,将 IsArrival 添加到 PlatformsNeeded,记住最大值

        【讨论】:

          猜你喜欢
          • 2011-02-17
          • 2023-01-08
          • 1970-01-01
          • 2019-03-21
          • 1970-01-01
          • 1970-01-01
          • 2010-10-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多