题意:有n个任务,每个任务有三个参数ri,di和wi,表示必须在时刻[ri,di]之内执行,工作量为wi。处理器执行速度可以变化,当执行速度为s时,工作量为wi。处理器的速度可以变化,当执行速度为s时,一个工作量为wi的任务需要执行wi/s个单位时间。任务不一定连续执行,可以分成若干块。求出处理器执行过程中最大速度的最小值。
首先按照左端点排序,然后二分答案,对于每一刻时间贪心地选当前未结束的任务中右端点最小的那个。
//Serene #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> #include<set> using namespace std; const int maxn=1e4+10; int T,n; int aa;char cc; int read() { aa=0;cc=getchar(); while(cc<'0'||cc>'9') cc=getchar(); while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); return aa; } struct Node{ int l,r,w; }node[maxn]; bool cmp(const Node& x,const Node& y) { return x.l==y.l? x.r<y.r:x.l<y.l; } struct Pp{ int noww,r; bool operator < (const Pp& b) const{return r<b.r;} }; multiset<Pp> G; multiset<Pp>::iterator it; bool check(int s) { G.clear(); int pos=1,time=node[1].l,x,y,ss; for(;;time++) { if(pos>n&&G.empty()) return 1; ss=s; while(ss>0&&!G.empty()) { it=G.begin(); x=it->noww; y=it->r; if(y<time) return 0; G.erase(it); if(x>ss) G.insert(Pp{x-ss,y}); ss-=x; } while(node[pos].l==time&&pos<=n) G.insert(Pp{node[pos].w,node[pos].r}),pos++; } if(G.empty()) return 1; return 0; } int main() { T=read(); while(T--) { memset(node,0,sizeof(node)); n=read();int l=0,r=0; for(int i=1;i<=n;++i) { node[i].l=read(); node[i].r=read(); node[i].w=read(); // l=max(l,(node[i].w-1)/(node[i].r-node[i].l+1)); r+=node[i].w; } sort(node+1,node+n+1,cmp); while(l<r-1) { if(!l) l++; int mid=(l+r)>>1; if(check(mid)) r=mid; else l=mid; } printf("%d ",r); } return 0; } /* 1 8 1 6 16 3 5 12 8 15 33 11 14 14 15 18 10 16 19 12 20 24 16 22 25 10 */