zoukankan      html  css  js  c++  java
  • 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?'
    ':' ');
    93         }
    94     }
    95     return 0;
    96 }
  • 相关阅读:
    1007 正整数分组
    Review: JQuery
    Summary: DOM modification techniques
    B
    D
    C
    hdu5592 倒序求排列+权值线段树
    主席树入门——询问区间第k大pos2104,询问区间<=k的元素个数hdu4417
    二维前缀和好题hdu6514
    莫比乌斯反演理解
  • 原文地址:https://www.cnblogs.com/gj-Acit/p/3213370.html
Copyright © 2011-2022 走看看