Uva 4254 Processor

题意:给n个任务,每个任务有三个参数ri,di,wi,代表任务i在[ri,di]内进行,工作量为wi,可把任务分块,求最大速度的最小值

题解:思路显然是二分,二分速度后再判断这个速度是否满足执行完所有任务。

显然怎么判断才是重点。  可以先想一下,到了某时间t,某任务ri==t,显然这个任务就要加入队列,然后什么工作先做呢,对于结束早的工作,显然是要先做的,(仔细思考一下)。

 

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 struct st{
 4         int l,r,w;
 5 };
 6 bool operator < (st a,st b)
 7 {
 8         return a.r > b.r;//以工作结束早出队
 9 }
10 st a[10000+20];
11 int L,R,n;
12 bool cmp(st a, st b)
13 {
14         return a.l < b.l; 
15 }
16 bool check(int s)
17 {
18         priority_queue <st> q;
19         int j = 1;
20         for(int i = L;i <= R; i++)
21         {
22                 int t = s;
23                 while(j!=n+1 && a[j].l<i) q.push(a[j++]); //如果没到最后一个,且时间为i时可以工作的工作便要加入队列
24                 while(!q.empty()&&t)
25                 {
26                         st ss = q.top();
27                         q.pop();
28                         if(ss.r<i) return false;
29                         if(ss.w>t)
30                         {
31                                 ss.w -= t;
32                                 t=0;
33                                 q.push(ss);
34                         }
35                         else t-=ss.w;
36                 }
37         }
38         if(q.empty()) return true;
39         return false;
40 }
41 int main()
42 {
43         ios::sync_with_stdio(false);
44         int test;
45         cin >> test;
46         while ( test -- )
47         {
48                 L=1000000000,R=-1;
49                 int sum = 0;
50                 cin >> n;
51                 for(int i = 1;i <= n;i++)
52                 {
53                         int x,y,z;
54                         cin >> a[i].l >> a[i].r >> a[i].w;
55                         L=min(L,a[i].l);
56                         R=max(R,a[i].r);
57                         sum += a[i].w;
58                 }
59                 sort(a+1,a+n+1,cmp);
60                 int left = 1,right = sum,ans=sum;
61                 while(left <= right)
62                 {
63                         int mid = (left+right) >> 1;
64                         if(check(mid))
65                         {
66                                 right=mid-1;
67                                 ans=min(ans,mid);
68                         }
69                         else left=mid+1;
70                 }
71                 cout << ans << endl;
72         }
73 }

 

posted on 2015-11-23 22:47  小松song  阅读(117)  评论(0)    收藏  举报

导航