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 }
原文地址:https://www.cnblogs.com/nowandforever/p/4485838.html