Description 多个调度任务,给出调度任务的起始时间和结束时间,问至少需要多少个设备能完成调度任务,在保证最小设备的情况,要求所有设备运行总时长最短。
每个设备的运行时长:从给这个设备的第一个任务开始计算到这个设备的最后一个任务结束,中间哪怕没有任务也要计算运行时长。
Input 输入的第一行包含一个正整数t(t≤100)?,代表共有t?组输入实例。每组输入实例中,第一行包含一个正整数n(n≤100)?,接下来输入n?行,每一行包含两个正整数l?和r(0≤l<r≤109)?,分别一个调度任务的开始时间和结束时间l?,r?。读入至文件结束为止。
Output 每组实例输出两个正整数,分别代表使用设备的数量,设备运行的总时长,每组实例输出占一行
Sample Input 1 5 1 3 3 6 2 4 5 7 6 9
Sample Output 2 13
思路
- 定义两类struct:work和machine,都拥有开始和结束时间,对机器而言,意味着被创建时的时间和工作结束的时间。
- 对work按开始时间从小到大排序
- 对每个work:查找是否有非繁忙的已创建机器,如有则直接让其执行,若无则新建机器执行
- 对机器进行排序,让结束之间靠后的机器排前面
why?要求所有设备运行总时长最短,则再在有空闲机器时,应该让结束繁忙状态时间最靠近开始这个任务的机器运行,不然会让设备运行总时长变长。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
int t,
maxWait[100];
struct work{
int start,end;
}works[100];
struct mechine{
int start,end;
}mechines[100];
int main() {
scanf("%d",&t);
while(t--){
int n;
scanf("%d",&n);
for (int i = 0; i < n; ++i) {
scanf("%d %d",&works[i].start,&works[i].end);
}
sort(works,works+n,[](work a,work b){
return a.start < b.start;
});
int mechineNum = 1;
mechines[0].start = works[0].start;
mechines[0].end = works[0].end;
for (int i = 1; i < n; ++i) {
int mechineAvailable = 0;
for (int j = 0; j < mechineNum; ++j) {
if(mechines[j].end <= works[i].start) {
mechineAvailable = 1;
mechines[j].end = works[i].end;
break;
}
}
if(!mechineAvailable) {
mechineNum++;
mechines[mechineNum-1].start = works[i].start;
mechines[mechineNum-1].end = works[i].end;
}
sort(mechines,mechines+mechineNum,[](mechine a,mechine b){
return a.end > b.end;
});
}
long long totalTime = 0;
for (int i = 0; i < mechineNum; ++i) {
totalTime += mechines[i].end - mechines[i].start;
}
printf("%d %lld\n",mechineNum,totalTime);
}
}
|