SGU 171 Sarov zones (贪心)
题目 SGU 171
相当好的贪心的题目!!!!!
题目意思就是说有K个赛区招收参赛队员,每个地区招收N[i]个,然后每个地区都有一个Q值,而N[i]的和就是N,表示总有N个参赛队员,每个队员都有他自己的P值,和他的权值W,只有当一个队员的P大于某一个地区的Q值时,权值W才能被记录在内,问怎样让着N个参赛队员选择地区才能让权值和最大。
贪心的思路就是按照权值W贪心
1、先按W的降序排序,优先考虑权值交大的。
2、歪了不影响后面的参赛队员,W较大的而且满足P>Q的,让其参加p>Q时Q最大的那一个。所以Q值按照降序排序。
3、如果某一个找不到一个Q使得P>Q,那么就让他参加Q最大的那一个赛区,这样可以给后面W更小的更多的机会
(这才发现贪心实在用的太巧秒了,以后更加的好好钻研)
实现见代码
1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #include<map> 5 #include<vector> 6 #include<set> 7 #include<stack> 8 #include<queue> 9 #include<algorithm> 10 #include<cmath> 11 #include<stdlib.h> 12 using namespace std; 13 #define MAX(a,b) (a > b ? a : b) 14 #define MIN(a,b) (a < b ? a : b) 15 #define MAXN 500005 16 #define INF 1000000007 17 #define mem(a) memset(a,0,sizeof(a)) 18 #define eps 1e-15 19 20 21 struct ZONE{int num,q,index;}zone[16005];//num招纳参赛人员的个数,Q值,以及保存这个地区最初编号(防止排序后打乱) 22 struct PERSON{int p,w,index,z;}per[16005];//P值,W值,编号,以及选择的地区 23 int K,N; 24 25 int cmp_zone(ZONE a,ZONE b)//按照Q值的从大到小排序,这样的话每次就只需要找到满足P>Q时,Q最大的哪一个 26 { 27 return a.q > b.q; 28 } 29 30 int cmp_per(PERSON a,PERSON b)//按照W的降序以及P的升序排序 31 { 32 if(a.p != b.p)return a.w > b.w; 33 return a.p < b.p; 34 } 35 36 int cmp_index(PERSON a,PERSON b)//按照参赛人员最初的编号排序,保证输出的顺序 37 { 38 return a.index < b.index; 39 } 40 41 int main() 42 { 43 while(~scanf("%d", &K)) 44 { 45 int i;N=0; 46 for(i=0;i<K;i++) 47 { 48 scanf("%d",&zone[i].num); 49 zone[i].index = i+1;//保存编号 50 N+=zone[i].num; 51 } 52 for(i=0;i<K;i++) 53 { 54 scanf("%d",&zone[i].q); 55 } 56 sort(zone, zone+K,cmp_zone);//排序 57 for(i=0;i<N;i++) 58 { 59 scanf("%d",&per[i].p); 60 } 61 for(i=0;i<N;i++) 62 { 63 scanf("%d",&per[i].w); 64 per[i].index = i; 65 per[i].z = -1; 66 } 67 sort(per,per+N,cmp_per); 68 int p = 0, z = 0, nz = 0;//p表示选择到了第p个人,Q值最大而且还没有选择完全的地区编号 69 while(p<N && nz<N) 70 { 71 while(!zone[nz].num)nz++;//找到目前还没有被选择的Q值最大的地区 72 z=nz; 73 while((per[p].p <= zone[z].q || !zone[z].num ) && z<N)//找到满足P>Q的第一个地区 74 { 75 z++; 76 } 77 if(z<N) 78 { 79 per[p].z = zone[z].index; 80 zone[z].num--; 81 } 82 else if(z == N) 83 { 84 per[p].z = zone[nz].index; 85 zone[nz].num--; 86 } 87 p++; 88 } 89 sort(per,per+N,cmp_index); 90 for(i=0;i<N;i++) 91 { 92 printf("%d%c",per[i].z,i==N-1?'\n':' '); 93 } 94 } 95 return 0; 96 }