题目大意
有n个任务,每个任务有一个起始时间和终止时间,一台机器一个时间最多处理一个任务,一台机器的运行时间定义为这台机器处理的任务中第一个任务开始的时间到最后一个任务结束的时间。
问你最少需要多少台机器
这里不求时间(省略)
解析
这种区间任务调度问题通常可行的一种实现方式是将左右端点看成独立的点来处理(用01来表示是左端点还是右端点),排一次序依次处理。
遇到左端点,num++,然后更新ans=max(ans, num),遇到右端点,num–,更新ans=max(ans, num)。
import java.util.Arrays;
import java.util.Scanner;
import java.util.Stack;
/**
* @Author: Elon
* @Date: 2019-11-02 15:48
*/
public class Main {
static class Node{
long x;
int id;
public Node(long x, int id) {
this.x = x;
this.id = id;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t, n;
Stack<Long> s = new Stack<>();
t = sc.nextInt();
while (t-->0){
int sumStart = 0, sumEnd=0;
n = sc.nextInt();
Node[] a = new Node[2*n];
int cnt = 0;
for (int i = 0;i<n;i++){
long l = sc.nextLong();
long r = sc.nextLong();
a[cnt++] = new Node(l, 0);
a[cnt++] = new Node(r, 1);
}
Arrays.sort(a, (o1,o2)->(int)(o1.x-o2.x));
long num=0;
long ans=0;
for (int i = 0;i<cnt;i++){
if (a[i].id==0){
if (num==ans){
num++;
sumStart+=a[i].x;
}else if (!s.isEmpty()) s.pop();
} else {
num--;
s.push(a[i].x);
}
ans = Math.max(ans, num);
}
while (!s.isEmpty()){
long tmp = s.pop();
sumEnd+=tmp;
}
System.out.println(ans+" "+ (sumEnd-sumStart));
}
}
}