• poj -2010 Moo University


    http://poj.org/problem?id=2010

    "Moo U"大学有一种非常严格的入学考试(CSAT) ,每头小牛都会有一个得分。然而,"Moo U"大学学费非常昂贵,并非每一头小牛都能支付的起,很多小牛都需要经济援助,但是学校只有有限的资金F。

    "Moo U"大学只会从C个学生里选N个学生出来,(N是奇数),但是希望N头小牛CSAT得分的中位数越高越好。输入N,C,F 接下来C行,每行包括一个得分和需要申请的经济援助,输出符合条件的最大中位数。

    首先对score排序,然后用堆维护前k小的数的和,左右扫描预处理,枚举中位数的位置。

    就是把每个数i的前n/2个数的最小和求出来用sum1[i]保存,i的后n/2个数的最小和求出来用sum2[i]保存。

    枚举中位数的时候只需要逆序枚举 p[i]+sum1[i]+sum2[i]<=F 满足条件的 i,输出中位数即可。

     1 #include <cstdio>
     2 #include <queue>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 const int maxn = 100010;
     7 int N,C,F;
     8 struct node
     9 {
    10     int s,c;
    11     bool operator < (const node &a) const  //定义堆的优先级 为大根堆
    12     {
    13         return c<a.c;
    14     }
    15 }p[maxn];
    16 
    17 bool cmp(const node& x,const node& y)  //按score排序
    18 {
    19     return x.s<y.s;
    20 }
    21 priority_queue<node>q1,q2;
    22 int f1[maxn],f2[maxn];
    23 void solve()
    24 {
    25     sort(p,p+C,cmp);
    26     int sum1=0,sum2=0;
    27     int ans=-1;   //没有符合条件的输出-1
    28     memset(f1,0,sizeof(f1));
    29     memset(f2,0,sizeof(f2));
    30     for(int i=0;i<C;i++)
    31     {
    32         if(i<N/2)  // i<N/2的时候  这个i不能选
    33         {
    34             q1.push(p[i]);
    35             sum1+=p[i].c;
    36             continue;
    37         }
    38         f1[i]=sum1;   //i之前的n/2的最小值
    39         if(p[i].c>=q1.top().c) continue;
    40         sum1-=q1.top().c;  //如果i比当前堆中最大元素小,需要更新
    41         q1.pop();
    42         sum1+=p[i].c;
    43         q1.push(p[i]);
    44     }
    45     for(int i=C-1;i>=0;i--)
    46     {
    47         if(i>C-1-N/2)
    48         {
    49             q2.push(p[i]);
    50             sum2+=p[i].c;
    51             continue;
    52         }
    53         f2[i]=sum2;
    54         if(p[i].c>=q2.top().c) continue;
    55         sum2-=q2.top().c;
    56         q2.pop();
    57         sum2+=p[i].c;
    58         q2.push(p[i]);
    59     }
    60     for(int i=C-1-N/2;i>=N/2;i--)
    61     {
    62         if(f1[i]+f2[i]+p[i].c<=F)
    63         {
    64             ans=p[i].s;break;
    65         }
    66     }
    67     printf("%d
    ",ans);
    68 }
    69 int main()
    70 {
    71     while(~scanf("%d%d%d",&N,&C,&F))
    72     {
    73         for(int i=0;i<C;i++)
    74             scanf("%d%d",&p[i].s,&p[i].c);
    75         solve();
    76     }
    77     return 0;
    78 }
  • 相关阅读:
    css兼容
    CSS 后代选择器
    解决ul里最后一个li的margin问题
    亿级数据库分片分库架构设计亿
    sem
    百度竞价匹配模式
    sql之left join、right join、inner join的区别
    .NET跨平台实践:再谈用C#开发Linux守护进程 — 完整篇
    .NET跨平台实践:用C#开发Linux守护进程
    php执行外部命令函数:exec()、passthru()、system()、shell_exec()对比
  • 原文地址:https://www.cnblogs.com/nowandforever/p/4485838.html
Copyright © 2020-2023  润新知