题目是求最小化最大值,很显然是二分,但是二分以后怎么判断mid是否可行并不容易。

  代码参考了网上一个博客的代码。巧妙之处在于一秒一秒的考虑,这样可以把处理速度mid直接转化成1秒内实际的量来解决(避免小数问题),然后贪心考虑每次处理最早结束的工作即可。注意我这里的代码t表示的是一整秒,譬如[1,2]即t=1。

  具体见代码:

 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <string.h>
 4 #include <queue>
 5 using namespace std;
 6 const int N = 10000 + 5;
 7 
 8 struct node
 9 {
10     int l,r,w;
11     bool operator < (const node & temp) const
12     {
13         return r > temp.r;
14     }
15     void read()
16     {
17         scanf("%d%d%d",&l,&r,&w);
18         r--;
19     }
20 }p[N];
21 
22 bool cmp(node a,node b) {return a.l < b.l;}
23 
24 int n;
25 bool can(int mid)
26 {
27     priority_queue<node> Q;
28     int t = 1, i = 1;
29     for(;;)
30     {
31         while(i <= n && p[i].l <= t) Q.push(p[i++]);
32         int x = mid;
33         while(x > 0 && !Q.empty())
34         {
35             node u = Q.top(); Q.pop();
36             int sub = min(x, u.w);
37             x -= sub;
38             u.w -= sub;
39             if(u.w > 0) Q.push(u);
40         }
41         t++;
42         if(!Q.empty() && Q.top().r < t) return false;
43         if(Q.empty() && i == n + 1) return true;
44     }
45     //return false;
46 }
47 
48 int main()
49 {
50     int T;
51     scanf("%d",&T);
52     while(T--)
53     {
54         scanf("%d",&n);
55         for(int i=1;i<=n;i++) p[i].read();
56         sort(p+1,p+1+n,cmp);
57         int L = 1, R = 1e9;
58         int ans = -1;
59         while(L <= R)
60         {
61             int mid = L + R >> 1;
62             if(can(mid))
63             {
64                 ans = mid;
65                 R = mid - 1;
66             }
67             else L = mid + 1;
68         }
69         printf("%d\n",ans);
70     }
71     return 0;
72 }