很容易想到二分,问题在与判断一个解的可行性。贪心,时间点最多两万,可以模拟每个时间点,将事件按开始时间排序,
每次优先选已经开始了的且结束时间最早的任务来做,如果某个任务在deadline之前还没有结束说明当前解不可行。
R的上界不太好估计,(远远达不到总和,但是比maxw大,因为任务在时间上有重叠),稍微取大点。
#include<bits/stdc++.h> using namespace std; const int maxn = 1e4+5; struct Job { int r,d,w; bool operator < (const Job &rh) const { return d > rh.d;//return r < rh.r || ( r == rh.r && d < rh.d); } void IN(){ scanf("%d%d%d",&r,&d,&w); } }J[maxn]; bool cmp(const Job&a, const Job&b) { return a.r < b.r; } const int maxd = 2e4; int n; bool ok(int m) { priority_queue<Job> q; for(int i = 2,j = 0; i <= maxd; i++){ while(j < n && J[j].r < i) q.push(J[j++]); int W = m; while(W>0 && q.size()){ Job cur = q.top(); q.pop(); if(cur.w <= W){ W-=cur.w; }else { if(cur.d <= i ) return false; cur.w -= W; q.push(cur); W = 0; } } if(j == n && q.empty()) return true; } return false; } int main() { //freopen("in.txt","r",stdin); int T; scanf("%d",&T); while(T--){ scanf("%d",&n); for(int i = 0; i < n; i++) J[i].IN(); sort(J,J+n,cmp); int L = 1, R = 1e4,M; for(; L<R ; ok(M)?R=M:L=M+1 ) M = (L+R)>>1; printf("%d ",L); } return 0; }