题目链接:UVa 1422 - Processor
优先队列 + 二分 + 贪心
两次应用贪心,第一次是对开始时间排序,然后枚举时间,任务开始时间小于当前枚举时间入优先队列,优先队列是按照结束时间越早优先级越高再次排序,这也是第二次贪心。当队列中的第一个元素的结束时间小于当前枚举时间的起始值时,返回0,表示这个速度不够大,需要继续二分增加速度,返回1,表示速度过大,继续二分减小速度。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; const int maxn = 1e4+100; int n; int w[maxn]; struct Mission { int l,r,w,i; bool operator < (const Mission &b) const { return r>b.r; } }p[maxn]; bool cmp(Mission a,Mission b) { if(a.l==b.l) return a.r<b.r; return a.l<b.l; } bool check(int mid) { Mission f; int mtime = 0, i=0, tmid; priority_queue<Mission> Q; for(int i=0;i<n;i++) { w[p[i].i] = p[i].w; } while(1) { while(i<n&&p[i].l<=mtime) Q.push(p[i++]); tmid = mid; while(Q.size()&&tmid!=0) { f = Q.top(); if(mtime>=f.r) return 0; w[f.i] -=tmid; if(w[f.i]>0) tmid = 0; if(w[f.i]<=0) { tmid = -w[f.i]; Q.pop(); } } if(i==n&&(Q.size()==0)) break; mtime++; } return 1; } int main() { int t; cin>>t; while(t--) { cin>>n; for(int i=0;i<n;i++) { cin>>p[i].l>>p[i].r>>p[i].w; p[i].i = i; w[i] = p[i].w; } sort(p,p+n,cmp); int l = 1, r= 5000,mid; while(l<=r) { mid = (l + r) / 2; if(check(mid)) r = mid-1; else l = mid + 1; } cout<<l<<endl; } return 0; }