题意:有 n 个工作,他的允许的工作时间是 [l,r] ,工作量是 v ,求CPU最速度的最小值。
分析:
可能太久没有做题了,竟然脑子反应好慢的。还是很容易想到二分,但是二分怎么转移呢?
可以看出,[l,r] 的区间范围不大,可以枚举,cpu 此时的二分答案 x,尽可能的贪心,怎么贪心呢,在同一速度情况下,是最先结束的优先。
而且,这一时刻,他能做很多任务,当 x 很大时,就在这里用优先队列来贪心安排任务。
其实这个题目中的那个图还是有干扰的,因为时时刻刻都要CPU速度为x。
#include <bits/stdc++.h> using namespace std; const int maxn = 1e4+5; struct Node { int l,r,v; }p[maxn],u; bool operator < (Node a,Node b) { return a.r>b.r; } int cmp(Node a,Node b) { return a.l < b.l; } int L,R,sum; int n; bool check(int x) { priority_queue<Node> Q; int k = 0; for(int i = L; i <= R; i++) { int t = x; while(k!=n&&p[k].l<i) Q.push(p[k++]); while(!Q.empty()&&t!=0) { u = Q.top(); Q.pop(); if(u.r < i) return false; if(u.v>t) { u.v-=t; t = 0; Q.push(u); } else t-=u.v; } } if(Q.empty()) return true; else 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++) { scanf("%d%d%d",&p[i].l,&p[i].r,&p[i].v); R = max(R,p[i].r); L = min(L,p[i].l); sum+=p[i].v; } sort(p,p+n,cmp); int ans; int l = 1,r = sum; while(l<=r) { int mid = (l+r)/2; if(check(mid)) { r = mid - 1; ans = mid; } else l = mid + 1; } printf("%d\n",ans); } return 0; }