版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhuxiyulu/article/details/77603333
/*
multiset+贪心
有m个作业,一台机器在同一时间只能运行一个作业,
已知每个作业的起始时间和结束时间,
求出最少要多少个机器以及最少的机器总运行时间
机器开始了就不会停,直到该机器不需要再作业
*/
#include <cstdio>
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
const int maxn=1e5+5;
typedef long long LL;
int n;
struct node
{
int s;
int e;
node() {}
node(int _s,int _e)
{
s=_s;
e=_e;
}
//set默认排序规则
bool operator <(const node &b)const
{
return e<b.e;
}
} a[maxn];
//初始排序规则
bool cmp1(node x,node y)
{
if(x.s==y.s)
return x.e<y.e;
return x.s<y.s;
}
multiset<node>cnt;
multiset<node>::iterator it;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=0; i<n; i++)
{
scanf("%d%d",&a[i].s,&a[i].e);
}
sort(a,a+n,cmp1);//初始排序
cnt.clear();
cnt.insert(a[0]);
for(int i=1; i<n; i++)
{
//寻找作业中结束时间>当前作业开始时间
node x=node(0,a[i].s);
it=cnt.upper_bound(x);
if(it!=cnt.begin())//不是第一个作业
{
it--;//前面一个作业结束时间必定<当前作业开始时间
//说明,当前作业可以与前一作业共用机器
int start=it->s;//保存前一作业开始时间
cnt.erase(it);
//用前一作业开始时间和当前作业结束时间更新前一作业
node y=node(start,a[i].e);
cnt.insert(y);
}
else
{
cnt.insert(a[i]);//新开一个机器
}
}
LL ans=0;//计算所有机器消耗总时间
for(it=cnt.begin(); it!=cnt.end(); it++)
{
ans+=(it->e-it->s);
}
printf("%d %I64d\n",(int)cnt.size(),ans);
}
return 0;
}