Moo University - Financial Aid POJ 2010(枚举)

原题

题目链接

题目分析

题目要求取中位数,我们可以枚举以每个牛的分数作为中位数,然后选出最省钱的方案,最后只需要看花钱数不超过F中的最高的中位数分数即可.说一下具体实现,先对所有牛按分数从小到大排序,选出最省钱的方案可以用优先队列来选,设half=n/2,当优先队列的牛超过half个的时候就把一个花费最多的弹出去,这样从小到大遍历一遍就可以记录分数比中位数小的那些牛的花费,记为lower[i],从大到小遍历一遍就可以记录分数比中位数大的那些牛的花费,记为upper[i],最后这个方案的总花费就是lower[i]+upper[i]+cow[i].cost.由于我们的牛是按分数从小到大排完序的,仔细观察可以发现最后这些方案具有二分性质,因此可以用二分快速找到答案.

代码

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <utility>
 4 #include <cstdio>
 5 #include <cmath>
 6 #include <cstring>
 7 #include <string>
 8 #include <vector>
 9 #include <stack>
10 #include <queue>
11 #include <map>
12 #include <set>
13
14 using namespace std;
15 typedef long long LL;
16 const int INF_INT=0x3f3f3f3f;
17 const LL INF_LL=0x3f3f3f3f3f3f3f3f;
18
19 typedef pair<int,int> P;
20 int lower[200000],upper[200000];
21 P cow[200000];
22
23 void clear(priority_queue<int> &que)
24 {
25     priority_queue<int> empty;
26     swap(empty,que);
27 }
28
29 int main()
30 {
31 //    freopen("black.in","r",stdin);
32 //    freopen("black.out","w",stdout);
33     int n,c,f;
34     cin>>n>>c>>f;
35     for(int i=1;i<=c;i++) scanf("%d %d",&cow[i].first,&cow[i].second);
36     sort(cow+1,cow+1+c);
37     int half=n>>1;
38     int sum=0;
39     priority_queue<int> que;
40     for(int i=1;i<=c;i++)
41     {
42         if(i<=half) lower[i]=INF_INT;
43         else lower[i]=sum;
44         que.push(cow[i].second);
45         sum+=cow[i].second;
46         if(i>half) sum-=que.top(),que.pop();
47     }
48     sum=0;
49     clear(que);
50     for(int i=c;i>=1;i--)
51     {
52         if(c-i<half) upper[i]=INF_INT;
53         else upper[i]=sum;
54         que.push(cow[i].second);
55         sum+=cow[i].second;
56         if(c-i>=half) sum-=que.top(),que.pop();
57     }
58  //   for(int i=1;i<=c;i++) printf("cow %d %d %d\n",i,cow[i].first,cow[i].second);
59  //   for(int i=1;i<=c;i++) printf("up %lld low %lld\n",upper[i],lower[i]);
60     int l=half+1,r=c-half+1;
61     while(r-l!=1)
62     {
63    //printf("l=%d r=%d\n",l,r);
64         int mid=l+r;
65         mid>>=1;
66         if(upper[mid]+cow[mid].second+lower[mid]<=f) l=mid;
67         else r=mid;
68     }
69     if(upper[l]+cow[l].second+lower[l]>f) cout<<-1<<endl;
70     else cout<<cow[l].first<<endl;
71
72   /*  int ans=-1;
73     for(int i=half+1;i<=c-half;i++)
74         if(upper[i]+lower[i]+cow[i].second<=f) ans=max(ans,cow[i].first);
75     cout<<ans<<endl;*/
76     return 0;
77 }

原文地址:https://www.cnblogs.com/VBEL/p/11418001.html

时间: 2024-10-31 07:54:37

Moo University - Financial Aid POJ 2010(枚举)的相关文章

Moo University - Financial Aid (poj 2010 优先队列 或者 二分)

Language: Default Moo University - Financial Aid Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 5551   Accepted: 1663 Description Bessie noted that although humans have many universities they can attend, cows have none. To remedy this p

挑战程序设计竞赛2.4习题:Moo University - Financial Aid POJ - 2010

Bessie noted that although humans have many universities they can attend, cows have none. To remedy this problem, she and her fellow cows formed a new university called The University of Wisconsin-Farmside,"Moo U" for short. Not wishing to admit

挑战程序设计竞赛3.1习题:Moo University - Financial Aid POJ - 2010

(原题见POJ2010) 这道题我之前采用了优先队列+预处理的方法求解(https://www.cnblogs.com/jacobfun/p/12244509.html),现在用二分的办法进行求解. 一开始我很纳闷,采用二分求解本题,如果二分的mid值不符合条件,按照二分右边界应该为mid - 1(我采用前闭后闭的二分),那么如果mid + xxx(xxx大于0)可以呢?(考虑mid不行是因为左边最小加起来大了,mid ~ mid + xxx中有极小值,使得mid + xxx的左边可以满足,那么

POJ 2010 Moo University - Financial Aid( 优先队列+二分查找)

POJ 2010 Moo University - Financial Aid 题目大意,从C头申请读书的牛中选出N头,这N头牛的需要的额外学费之和不能超过F,并且要使得这N头牛的中位数最大.若不存在,则输出-1(一开始因为没看见这个,wa了几次). 这个题的第一种做法就是用两个优先队列+贪心. /* * Created: 2016年03月27日 14时41分47秒 星期日 * Author: Akrusher * */ #include <cstdio> #include <cstdl

poj2010 Moo University - Financial Aid

Moo University - Financial Aid 题意: 一个私立学校的学生要申请奖学金,而学校的金额有限.因此,学校希望在金额不超过F的情况下从C中选得N对数. 给出三个数N,C,F.分别代表在C对数中要取得N对数. 而每对数分别代表成绩,跟申请金额.要求取得N对数中的总金额不超过F的条件下,然取得中间的以为学生的成绩最高.(N为even) 算法分析: 本题有两种解法,一种是用优先队列,一种是二分; 一.利用堆实现 先说堆的实现方法,我们能够现对头尾的N/2进行处理,由于头尾的N/

poj 2010 Moo University - Financial Aid(优先队列(最小堆)+ 贪心 + 枚举)

Description Bessie noted that although humans have many universities they can attend, cows have none. To remedy this problem, she and her fellow cows formed a new university called The University of Wisconsin-Farmside,"Moo U" for short. Not wish

POJ 2010 - Moo University - Financial Aid 初探数据结构 二叉堆

考虑到数据结构短板严重,从计算几何换换口味= = 二叉堆 简介 堆总保持每个节点小于(大于)父亲节点.这样的堆被称作大根堆(小根堆). 顾名思义,大根堆的数根是堆内的最大元素. 堆的意义在于能快速O(1)找到最大/最小值,并能持续维护. 复杂度 push() = O(logn); pop() = O(logn); BinaryHeap() = O(nlogn); 实现 数组下标从1开始的情况下,有 Parent(i) = i >> 1 LChild(i) = i << 1 RChi

poj 2010 Moo University - Financial Aid 大顶堆维护最小和

题意: 有c有牛,从中选(n-1)/2头,使他们的得分中位数最大且需要的资金援助和不超过f. 分析: 堆的运用大顶堆维护最小和. 代码: //poj 2010 //sep9 #include <iostream> #include <queue> #include <algorithm> using namespace std; const int maxN=100024; int dpl[maxN],dpr[maxN]; priority_queue<int&g

poj2010(Moo University - Financial Aid)优先队列

Description Bessie noted that although humans have many universities they can attend, cows have none. To remedy this problem, she and her fellow cows formed a new university called The University of Wisconsin-Farmside,"Moo U" for short. Not wish