如何解决如何找到完成 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 举报,一经查实,本站将立刻删除。