题意:
给出n个任务完成区间以及工作量,求出最快处理速度.
思路:
用二分搜索匹配最优速度,其中还用到优先队列辅助.
枚举所有截止时间,在此时间内的都进队,按照工作截止时间越早越先出队,如果截止时间不及枚举的截止时间,则错过
代码:
#include<cstdio>
#include<queue>
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
const int N = 10005;
int n;
struct Work {
double r, d, w;
bool operator < (const Work& a)const {
return d>a.d;//工作按照结束时间在队内调整
}
}work[N];
bool cmp(Work a, Work b) {
return a.r < b.r;
}
void init() {
scanf("%d", &n);
for(int i=0; i<n; i++) scanf("%lf%lf%lf", &work[i].r, &work[i].d, &work[i].w);
sort(work, work+n, cmp);//工作按照起始时间进队
}
bool judge(int m) {
priority_queue<Work> qu;
int wn = 0;
for(int i=1; i<=20000; i++) {
int sum = m;
while(work[wn].r<i && wn<n) qu.push(work[wn++]);
while(!qu.empty() && sum) {//每秒内工作量没用完而且还有工作没完成.
Work tmp = qu.top();
qu.pop();
if(tmp.d < i) return false;//作业已错过
if(sum >= tmp.w) sum -= tmp.w;
else {
tmp.w -= sum;
qu.push(tmp);
sum = 0;
}
}
if(qu.empty() && wn == n) return true;
}
return false;
}
int deal() {
int l=0, r=5000, mid;
while(l<=r) {
mid = (l+r)/2;
if(judge(mid)) r = mid-1;
else l = mid+1;
}
return l;
}
int main() {
int kase;
scanf("%d", &kase);
while(kase--) {
init();
printf("%d\n", deal());
}
return 0;
}