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 "); 80 else{ 81 printf("YES "); 82 for(int i=1;i<=m;i++){ 83 printf("%d ",temp[i]); 84 } 85 printf(" "); 86 } 87 } 88 }