題目地址: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;
}