#include<bits/stdc++.h>
#define debu
using namespace std;
const int INF=1e7;
const int maxn=1e4+50;
struct point
{
int l,r,w;
bool operator < (const point& rhs) const
{
return r>rhs.r;
}
};
int n;
point a[maxn];
priority_queue<point> q;
int cmp(point a,point b)
{
if(a.l==b.l) return a.r<b.r;
else return a.l<b.l;
}
int check(int speed)
{
//cout<<"*******************"<<endl;
int num=0,time=0;
while(!q.empty()) q.pop();
while(1)
{
while(num<n&&a[num].l<=time)
{
q.push(a[num]);
// cout<<num<<" "<<a[num].l<<" "<<a[num].r<<" "<<time<<" "<<q.empty()<<endl;
num++;
}
int tot=0,now=speed;
while(!q.empty()&&now)
{
point tmp=q.top();
// cout<<tmp.l<<" "<<tmp.r<<endl;
q.pop();
int make=min(tmp.w,now);
tmp.w-=make;
now-=make;
if(tmp.w) q.push(tmp);
}
time++;
if(!q.empty()&&q.top().r<=time)
{
// cout<<speed<<" 0"<<endl;
return 0;
}
if(q.empty()&&num==n)
{
//cout<<speed<<" 1"<<endl;
return 1;
}
}
}
void solve()
{
int l=0,r=INF,mid;
while(l<r)
{
mid=l+(r-l)/2;
// cout<<mid<<endl;
if(check(mid)) r=mid;
else l=mid+1;
}
printf("%d\n",l);
}
int main()
{
#ifdef debug
freopen("in.in","r",stdin);
#endif
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=0; i<n; i++)
scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].w);
sort(a,a+n,cmp);
solve();
}
return 0;
}
题目地址:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2255
题解:按照左端点排序,二分速度,模拟判断是否合法。使用优先队列,以右端点为关键字,先处理右端点较小值。模拟时判断该秒可做多少工作,不断减去,若仍未做完,则加入队列,不断判断,当当前时间time>=a[i].r且队列非空时该速度不合法,若队列为空且num==n时该速度合法。