有n个任务,每个任务有ri,di,wi;代表任务的[ri,di]代表可以做这个任务的时间区间,而wi代表这个任务的工作量;现在有有个处理器,如果它的执行速度是s,则完成第i个任务所需时间wi/s;要求算出处理器执行过程中最大速度的最小值
思路很简单二分,但如何模拟是难点,可以模拟处理器每一秒的工作,对于每一秒来说,用优先队列储存当前时间下可以处理的任务,优先处理d小的,如果处理完了,那么处理下一个任务,如果没处理完,时间加一。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#define eps 1e-6
#define LL long long
using namespace std;
const int maxn = 10000 + 100;
const int INF = 0x3f3f3f3f;
int n;
struct Task {
int r, d, w;
bool operator < (const Task& A) const { return d > A.d; }
};
bool cmp(Task A, Task B) {
return A.r < B.r;
}
Task tasks[maxn];
void init() {
cin >> n;
for(int i = 0; i < n; i++) {
cin >> tasks[i].r >> tasks[i].d >> tasks[i].w;
}
sort(tasks, tasks+n, cmp);
}
bool check(int speed) {
priority_queue<Task> q;
int now = 1, pcnt = 0;
while(pcnt < n || !q.empty()) {
while(pcnt < n && tasks[pcnt].r == now) q.push(tasks[pcnt++]);
int work = speed; //单位时间的工作量
while(!q.empty() && work) {
Task tmp = q.top(); q.pop();
if(work > tmp.w) work -= tmp.w;
else if(work == tmp.w) {
if(!q.empty() && q.top().d == now+1) return false;
work = 0;
}
else {
if(tmp.d == now+1) return false;
tmp.w -= work;
work = 0;
q.push(tmp);
}
}
now++;
}
return true;
}
void solve() {
int left = 1, right = INF;
while(left < right) {
int mid = left + (right - left) / 2;
if(check(mid)) right = mid;
else left = mid + 1;
}
cout << right << endl;
}
int main() {
//freopen("input.txt", "r", stdin);
int T; cin >> T;
while(T--) {
init();
solve();
}
return 0;
}