微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何找到完成 n 个作业的最少处理器数量

如何解决如何找到完成 n 个作业的最少处理器数量

我最初在我的大学考试中看到了这个问题(不幸的是,我无法再访问这个问题和测试用例,所以这是凭记忆描述的)。问题是,您有 n 个带有开始和完成时间的作业,您必须找到可以完成所有作业的最少处理器数量。处理器只能执行不相交的作业(不重叠的作业)。

示例测试用例: 有 5 个作业(分别给出了开始和结束时间):

1 11
2 3
3 6
4 6
10 13

答案是您至少需要 3 个处理器才能完成所有作业。

processor 1: 1-11
processor 2: 2-3 4-6 10-13
processor 3: 3-6

我对此的想法是使用一组对,其中完成时间为第一,开始时间为第二。这样,作业将按完成时间排序。然后我会继续迭代该集合并删除所有与该迭代不相交的进程(使用贪婪算法找到单个处理器可以调度的最大作业数),然后我的答案将是它所花费的迭代次数直到集合为空。

然而,这并不适用于所有测试用例。我相信这可能是因为算法太慢了,因为在集合中插入和删除需要 log n 时间(我对 n 个元素这样做)。然后我也一次又一次地迭代这个集合,直到它为空。

我的问题是,有没有更好的方法来做到这一点?

代码

#include <iostream>
#include <set>
#include <vector>
#include <utility>
#include <algorithm>
using namespace std;

int main()
{
    
    int t;
    cin >> t;
    while(t--)
    {
        int n;
        cin >> n;
        set<pair<int,int>> a;
        for(int i=0; i < n; ++i)
        {
            int s,f;
            cin >> s >> f;
            a.insert({f,s});
        }
        int cnt = 0;
        while(!a.empty())
        {
            auto range = pair<int,int>(*a.begin());
            a.erase(a.begin());
            for(auto t = a.begin(); t!= a.end(); ++t)
            {
                if(t->second > range.first)
                {
                    range.first = t->second;
                    a.erase(t);
                }
            }
            cnt++;
        }
        cout << cnt << endl;
    }
}

第一行是测试用例的数量

输入的第二行是作业数 n。

接下来的 n 行表示每个作业,第一个数字是开始时间,第二个数字是结束时间

解决方法

如果开始和结束时间的限制很低,它可以在 O(n) 时间内完成得更快。我们可以创建一个 dp 数组,其中对于每个作业,我们将执行 dp[job[i].start]+=1 和 dp[job[i].end+1]-=1。从中计算前缀数组后,最大数量将是我们的答案。这个问题与最小讲堂数非常相似。详情请参考https://www.geeksforgeeks.org/minimum-halls-required-for-class-scheduling/

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。