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 <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <fstream>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define inll(n) scanf("%I64d",&(n))
#define inll2(x1,x2) scanf("%I64d%I64d",&(x1),&(x2))
#define inlld(n) scanf("%lld",&(n))
#define inlld2(x1,x2) scanf("%lld%lld",&(x1),&(x2))
#define inf(n) scanf("%f",&(n))
#define inf2(x1,x2) scanf("%f%f",&(x1),&(x2))
#define inlf(n) scanf("%lf",&(n))
#define inlf2(x1,x2) scanf("%lf%lf",&(x1),&(x2))
#define inc(str) scanf("%c",&(str))
#define ins(str) scanf("%s",(str))
#define out(x) printf("%d\n",(x))
#define out2(x1,x2) printf("%d %d\n",(x1),(x2))
#define outf(x) printf("%f\n",(x))
#define outlf(x) printf("%lf\n",(x))
#define outlf2(x1,x2) printf("%lf %lf\n",(x1),(x2));
#define outlld(x) printf("%lld\n",(x))
#define outc(str) printf("%c\n",(str))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
#define mem(X,Y) memset(X,Y,sizeof(X));
typedef vector<int> vec;
typedef long long ll;
typedef pair<int,int> P;
const int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
const int INF=0x3f3f3f3f;
const ll mod=1e9+7;
ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
const bool AC=true;

struct point{
ll a;
ll b;
};
point p[100010];
ll l[100005];
ll r[100005];
bool cmp(point x,point y){
 return x.a>y.a;
}
int main()
{

    ll c,n,ans,sum,sum1,sum2,f;
    while(scanf("%lld %lld %lld",&c,&n,&f)==3){
    rep(i,0,n)
    inlld2(p[i].a,p[i].b);
    sort(p,p+n,cmp);
    sum1=sum2=0;sum=0;
    priority_queue <int> que1;
    priority_queue <int> que2;
    mem(l,0);
    mem(r,0);
    rep(i,0,n){ //遍历数组,找出left[i],right[i];
    if(i<c/2){  //i左边的数少于c/2时,全部加入队列
    sum1+=p[i].b;
    que1.push(p[i].b);
    }
    else{
    l[i]=sum1;
    if(p[i].b<que1.top()){
    sum1-=que1.top(); //更新最小值
    sum1+=p[i].b;
    que1.pop();
    que1.push(p[i].b);
    }
    }
    }
    per(i,0,n){
    if(i>=n-c/2){
    sum2+=p[i].b;
    que2.push(p[i].b);
    }
    else{
    r[i]=sum2;
    if(p[i].b<que2.top()){
    sum2-=que2.top();
    sum2+=p[i].b;
    que2.pop();
    que2.push(p[i].b);
    }
    }
    }
    ans=-1;
    rep(i,c/2,n-c/2){
    sum=p[i].b+l[i]+r[i];
    if(sum<=f){
    ans=p[i].a;
    break;
    }
    }
    outlld(ans);
    }
    return 0;
}

这一题的第二种做法是二分

时间: 2024-10-14 05:20:42

POJ 2010 Moo University - Financial Aid( 优先队列+二分查找)的相关文章

poj -2010 Moo University - Financial Aid (优先队列)

http://poj.org/problem?id=2010 "Moo U"大学有一种非常严格的入学考试(CSAT) ,每头小牛都会有一个得分.然而,"Moo U"大学学费非常昂贵,并非每一头小牛都能支付的起,很多小牛都需要经济援助,但是学校只有有限的资金F. "Moo U"大学只会从C个学生里选N个学生出来,(N是奇数),但是希望N头小牛CSAT得分的中位数越高越好.输入N,C,F 接下来C行,每行包括一个得分和需要申请的经济援助,输出符合条件

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

POJ - 2010 Moo University - Financial Aid 贪心+优先队列

题目大意:有C头牛,每头牛都有相应的分数和需求,要求在这C头牛中选出N头,使得这N头牛中的分数的中位数达到最大,且需求之和小于等于F 解题思路:先按成绩排序 再用两个数组保留最小需求之和 left数组保留第i个位置左边的 N/2个最小需求之和 right数组保留第i个位置右边的 N/2个最小需求之和 如何保留最小的需求之和呢,扫描两遍(左右),用优先队列保留N / 2个最小需求 最后只需要判断一下 left[i] + right[i] + 第i头牛的需求 <= F就可以了 #include<c

POJ 2010 Moo University - Financial Aid 堆的高级应用 -- 维护最小(最大和)

题目大意:有N头牛,每头牛两个权值,A和B.从这N头牛中选取C头牛,使得: 1.这些牛中A权值的中位数尽量大. 2.这些牛的B权值的和小于题中所给的F 输出这个最大的A权值的中位数:如果没有满足题意的解,就输出-1.值. 思路: 堆有一个神奇的功能.假设上图是一个数组,在B从A到C移动的过程中,利用大根堆可以维护出B在所有位置时,从A到B中选K个值的和的最小值,并在nlogn内得到答案. 方法如下:先把[A,A + K]的元素加入到一个大根堆中,记录它们的总和.之后让B不断向后循环,把B加入到大

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

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

poj2010 Moo University - Financial Aid

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