Preparing for the Contest

 Codeforces Round #222 (Div. 1)B:http://codeforces.com/contest/377/problem/B
题意:m个任务,每个任务会有一个复杂度,然后给你n个人,每个人会有一个能力值,一个任务只有被能力值不少于它的人所完成。并且每个人完成任务会有一个费用,这个费用是固定,不论完成多少任务,只要付一次,一个任务只由一个人完成,一个人可以完成多个任务,但是每个人每天只能完成一个任务,现在给以一个总的费用,让你找出在不超过总费用的情况下,去完成这m个任务,并且要求时间短。
题解:想到了贪心,但是没想到要二分天数。最多需要m天去完成,这是显然的,这是在能够完成的前提下。还是那句话,二分一定要有线性关系,这里的线性关系就是,天数越多,任务被完成的可能性越大。对于t天来说,对于任务中复杂度最高的那个任务来说,应该找一个能力水平不小于它,并且费用最少的那个人来完成,这样的费用一定是最少的,那个人花了1天完成了那个任务之后,对于其他任务来说,它肯定是可以完成的,而且他完成后面的任务都是不需要费用的,所以再让他完成t-1个任务。只花了一个任务钱,对于前面的任务来说,要想完成,又要找一个人,让他来完成,重复上面的,直到所有的任务都被完成。实现的时候,可以用一个优先队列来存,然后任务按复杂度从小到大的顺序排序,人按照能力值从小到大排序。然后每一次选择一个当前最复杂的那个任务,把所有比它大=的人都放进队列,然后选择一个最小,去完成前t个任务,然后不断重复,不断二分,最后得到答案。
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<queue>
 6 using namespace std;
 7 const int N=1e5+10;
 8 struct Node{
 9   int val;
10   int id;
11   bool operator<(const Node a)const{
12      return val<a.val;
13   }
14 }task[N];
15 struct Edge{
16   int b;
17   int c;
18   int id;
19   bool operator<(const Edge a)const{
20       return b<a.b;
21   }
22 }stu[N];
23 struct result{
24   int id;
25   int cost;
26   bool operator<(const result a)const{
27     return cost>a.cost;
28   }
29 };
30 int ans[N],temp[N];
31 int n,m,s;
32 bool judge(int t){
33     int len=m,p=n,tp=s;
34     priority_queue<result>Q;
35      while(len>=1){
36         while(p>=1&&stu[p].b>=task[len].val){
37             result aaa;
38             aaa.cost=stu[p].c;
39             aaa.id=stu[p].id;
40             Q.push(aaa);
41             p--;
42         }
43         if(Q.size()==0)return false;
44         result ta=Q.top();
45         Q.pop();
46         tp-=ta.cost;
47         if(tp<0)return false;
48         for(int i=max(1,len-t);i<=len;i++)
49             ans[task[i].id]=ta.id;
50         len-=t;
51      }
52     for(int i=1;i<=m;i++)
53        temp[i]=ans[i];
54     return true;
55 }
56 int main(){
57   while(~scanf("%d%d%d",&n,&m,&s)){
58        for(int i=1;i<=m;i++){
59           scanf("%d",&task[i].val);
60           task[i].id=i;
61        }
62        for(int i=1;i<=n;i++)
63           scanf("%d",&stu[i].b);
64        for(int i=1;i<=n;i++){
65           scanf("%d",&stu[i].c);
66           stu[i].id=i;
67        }
68        sort(task+1,task+m+1);
69        sort(stu+1,stu+n+1);
70        int minn=-1,l=1,r=m;
71        while(l<=r){
72           int mid=(l+r)/2;
73           if(judge(mid)){
74             r=mid-1;
75            minn=mid;
76           }
77           else l=mid+1;
78        }
79       if(minn==-1)printf("NO\n");
80       else{
81         printf("YES\n");
82         for(int i=1;i<=m;i++){
83             printf("%d ",temp[i]);
84         }
85         printf("\n");
86       }
87   }
88 }
View Code

 

posted on 2014-08-04 13:58  天依蓝  阅读(238)  评论(0编辑  收藏  举报

导航