题目链接:Schedule
题意:已知一些任务的开始时间和结束时间,一台机器同时只能运行一个任务(机器中间不关闭运行),求在使用最少机器工作的前提下机器工作的最短时间
思路:将开始时间标记为1,结束时间标记为-1。
按照时间大小对这
2n
个时间从小到大排序,然后遍历计算前缀和,当前缀和每次增加1的时候,说明需要新开一台机器才能运行,这样可以寻找到每台机器的开始时间。同理,逆序遍历计算前缀和,可以记录下每一台机器的结束时间。最后把每一台机器的时间相加即可。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=1e5+5;
struct node
{
int val,flag;
bool operator < (const node&A)const
{
if(val==A.val)//val相等时,结束时间排在开始时间之前
return flag<A.flag;
return val<A.val;
}
}p[maxn<<1];
int L[maxn],R[maxn];
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
scanf("%d%d",&p[i*2-1].val,&p[i*2].val);
p[i*2-1].flag=1,p[i*2].flag=-1;
}
n<<=1;
sort(p+1,p+1+n);
int tot=0,ans=0;
for(int i=1;i<=n;++i)
{
tot+=p[i].flag;
if(tot>ans)
{
ans=tot;
L[tot]=p[i].val;//开始时间
}
}
tot=0,ans=0;
for(int i=n;i>0;--i)
{
tot-=p[i].flag;
if(tot>ans)
{
ans=tot;
R[tot]=p[i].val;//结束时间
}
}
LL sum=0;
for(int i=1;i<=ans;++i)
sum+=(LL)(R[i]-L[i]);
printf("%d %lld\n",ans,sum);
}
return 0;
}