题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=6180
思路:
1.贪心。将每个安排分成两个:起始(标号为0)和终止(标号为1)。按照时间顺序排序,每次遇到一个起始事件时,num++(代表当前机器不能满足条件,需要一台新的机器);每次遇到一个终止事件时,num--(代表当前机器运行结束)。则机器个数=max{num}(代表同时运行的机器个数)。
2.时间计算。时间=完成工作的时间+等待时间。工作时间可通过输入时累加,等待时间可通过用一栈记录当前完成工作的结束时间。当遇到一起始事件时,等待时间=起始事件时间-当前最后工作的完成时间(即栈顶元素),同时出栈。当遇到一终止事件时,将该事件的时间入栈。
3.若起始时间与终止时间相同时,应先按照终止时间排序(可以理解为将所有终止时间往左移动了一个极小(大于0)的距离)。
#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define debug
using namespace std;
typedef long long LL;
const int maxn=200000+50;
struct Node
{
LL x;
int id;
Node() {}
Node(LL x,int id):x(x),id(id) {}
};
LL sum;;
stack<LL> s;
Node a[maxn];
int ans,n,num,cnt;
int cmp(Node a,Node b)
{
if(a.x==b.x) return a.id>b.id;
else return a.x<b.x;
}
void init()
{
ans=0,sum=0,num=0,cnt=0;
while(!s.empty()) s.pop();
}
int main()
{
#ifdef debu
freopen("1010.in","r",stdin);
#endif // debug
int t;
scanf("%d",&t);
while(t--)
{
init();
scanf("%d",&n);
for(int i=0; i<n; i++)
{
LL l,r;
scanf("%lld%lld",&l,&r);
a[cnt++]=Node(l,0);
a[cnt++]=Node(r,1);
sum+=r-l;
}
sort(a,a+cnt,cmp);
for(int i=0; i<cnt; i++)
{
if(a[i].id==0)
{
num++;
if(!s.empty())
{
LL pre=s.top();
s.pop();
sum+=a[i].x-pre;
}
}
else
{
num--;
s.push(a[i].x);
}
ans=max(ans,num);
}
printf("%d %lld\n",ans,sum);
}
return 0;
}