好题。算法不难,实现巧妙
堆(按结束时间排序)
链表 表示已经占据的空间的开始点和长度 用set表示了
队列 等待分配的
代码
#include<iostream>
#include<cstdio>
#include<set>
#include<queue>
#define PII pair<int,int>
using namespace std;
set<PII>s;
priority_queue<PII>q;
queue<PII>wait;
int ans,cnt;
bool check(int t,int m,int p)
{
set<PII>::iterator it,jt;
for(it=s.begin();it!=s.end();++it)
{
jt=it;
++jt;
if(jt!=s.end())
{
int st=it->first+it->second;
if(jt->first-st>=m)
{
s.insert(make_pair(st,m));
q.push(make_pair(-t-p,st));
return true;
}
}
}
return false;
}
void free(int t)
{
while(!q.empty()&&-q.top().first<=t)
{
int f=-q.top().first;
while(!q.empty()&&-q.top().first==f)
{
PII top=q.top();
q.pop();
set<PII>::iterator it=s.lower_bound(make_pair(top.second,0));
s.erase(it);
}
ans=f;
while(!wait.empty())
{
PII ft=wait.front();
if(check(f,ft.first,ft.second))wait.pop();
else break;
}
}
}
int main()
{
int n,t,m,p;
scanf("%d",&n);
s.insert(make_pair(-1,1));
s.insert(make_pair(n,1));
while(scanf("%d%d%d",&t,&m,&p)&&(t||m||p))
{
free(t);
if(!check(t,m,p))++cnt,wait.push(make_pair(m,p));
}
free(2e9);
printf("%d\n%d\n",ans,cnt);
return 0;
}