题意:

在C头牛里选N头牛,每头牛需要花掉一定经费ai才能得到一定得bi分,在不超过经费F的情况下,使得N头牛的得分中位数最大。(1 <= N <= 19,999,奇数) (N <= C <= 100,000)(0 <= F <= 2,000,000,000)

输入:(N,C,F;ai,bi)

3 5 70
30 25
50 21
20 20
5 18
35 30

输出:

   35
分析:
最朴素的办法:按分数从小到大排列,枚举原点,从右到左扫,区间为[(m+1)/2,n-(m+1)/2],计算左边最小和和右边最小和,判断是否是满足条件,满足即输出。
显然这种n2的办法是不行的。
我们要减复杂度,就要在枚举原点的同时维护左右两边最小和,如何维护?
方法一(较复杂,但是是一个解决问题的想法):
针对右边,我们的需求是:不断加入值,求前k小的和。我们建立一个大根堆,并在开始的时候记录一个sumR,每加入一个点,如果小于大根堆顶,便更新sumR,弹出堆顶,压入新点。
针对左边,我们的需求是:不断删去值,求前k小的和。这个方法就困难在这里,我们在区间[1,(2n-m-1)/2]新建立一个数组new,按花销从小到大排序,同样时原位置小的在前,同时记录该点是否要去除(usd)。什么意思呢?我们最开始在原数组统计的和sumL=sum(1->(m-1)/2),并在(m-1)/2处设立一个指针p。在原数组删去一个数的时候,如果在new对应的位置在p右边则不用管,标记usd=1。如果在p位置或p位置的左边,就在sumL删除这个数,p向右移至第一个usd没被标记的地方,sumL加入这个新数。
方法二:
我们发现不断删去值,求前k小的和要比不断加入值,求前k小的和更加困难,那我们就提前从左向右扫一边,那么针对左边,就是和右边一样的需求了(不断加入值,求前k小的和)。
这道题还是费了我一点脑子的...
 
代码:
 #include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define RG register int
#define rep(i,a,b) for(RG i=a;i<=b;++i)
#define per(i,a,b) for(RG i=a;i>=b;--i)
#define ll long long
#define inf (1<<29)
#define maxn 100005
using namespace std;
int n,m,F,L,R,rt;
int sL,sR;
int po[maxn];
struct D{
int cost,sco;
inline int operator < (const D &tmp)const{
return sco<tmp.sco;
}
}a[maxn];
struct Dat{
int val,id,usd;
inline int operator < (const Dat &tmp)const{
return (val==tmp.val)?id<tmp.id:val<tmp.val;
}
}b[maxn];
priority_queue<int> que;
inline int read()
{
int x=,f=;char c=getchar();
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} void work()
{
L=(m+)/,R=n-(m-)/; int end=(*n-m+)/;
per(i,n,end) que.push(a[i].cost),sR+=a[i].cost; end=(*n-m-)/,rt=(m-)/;
rep(i,,end) b[i].val=a[i].cost,b[i].id=i;
sort(b+,b++end);
rep(i,,end) po[b[i].id]=i;
rep(i,,rt) sL+=b[i].val; end=(*n-m+)/;
per(O,R,L)
{
if(sL+sR+a[O].cost<=F) {printf("%d\n",a[O].sco);return;} if(a[O].cost<que.top()) sR-=que.top()-a[O].cost,que.pop(),que.push(a[O].cost); b[po[O-]].usd=;
if(po[O-]<=rt)
{
while(b[rt].usd&&rt<=end) rt++;
if(rt==(*n-m+)/) {puts("-1");return;}
sL+=b[rt].val-a[O-].cost;
}
}
puts("-1");return;
} void dif()
{
per(i,n,)
if(a[i].cost<=F){printf("%d\n",a[i].sco);return;}
exit(); } int main()
{
m=read(),n=read(),F=read();
rep(i,,n) a[i].sco=read(),a[i].cost=read();
sort(a+,a++n);
L=(m+)/,R=n-(m-)/;
if(m==) dif();
else work();
return ;
}
 

Moo University - Financial Aid [POJ2010] [堆]的更多相关文章

  1. POJ_2010 Moo University - Financial Aid 【堆预处理】

    一.题面 POJ2010 二.分析 堆预处理 首先可以考虑吧随便取一个点,判断两侧的最小的总费用是多少,然后相加判断是否满足条件.如果直接判断会超时,所以需要用大根堆预处理一下.先看从分数最小的往最大 ...

  2. POJ 2010 Moo University - Financial Aid(堆维护滑窗kth,二分)

    按照score排序,贪心,从左到右用堆维护并且记录前面的最小N/2个花费之和. 然后从右向左枚举中位数,维护N/2个数之和加上并判断是否满足条件.(stl的队列没有clear(),只能一个一个pop. ...

  3. 【POJ - 2010】Moo University - Financial Aid(优先队列)

    Moo University - Financial Aid Descriptions 奶牛大学:奶大招生,从C头奶牛中招收N(N为奇数)头.它们分别得分score_i,需要资助学费aid_i.希望新 ...

  4. Divide and conquer:Moo University - Financial Aid(POJ 2010)

    Moo University - Financial Aid 其实是老题了http://www.cnblogs.com/Philip-Tell-Truth/p/4926008.html 这一次我们换二 ...

  5. Moo University - Financial Aid

    Moo University - Financial Aid Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 6020 Accep ...

  6. poj 2010 Moo University - Financial Aid

                                                                                                Moo Univ ...

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

    POJ 2010 Moo University - Financial Aid 题目大意,从C头申请读书的牛中选出N头,这N头牛的需要的额外学费之和不能超过F,并且要使得这N头牛的中位数最大.若不存在 ...

  8. poj 2010 Moo University - Financial Aid 最大化中位数 二分搜索 以后需要慢慢体会

    Moo University - Financial Aid Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 6599   A ...

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

    Description Bessie noted that although humans have many universities they can attend, cows have none ...

随机推荐

  1. 【第一部分】04Leetcode刷题

    一.反转链表 II /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; ...

  2. mongodb 安装时错误

    1.安装MongoDB进度条长时间不动 根据在网上搜的步骤安装mongoDB到这步,就基本上卡死不动,在网上查到的办法是死等,等了半个小时,但运气不好半个小时也不一定安装成功. 如果进行到这步,卡死在 ...

  3. Vue小问题汇总

    1.element-UI等组件更改默认样式: >>> https://vue-loader-v14.vuejs.org/zh-cn/features/scoped-css.html ...

  4. 如何配置使用HTML在线编辑工具

    如何配置使用HTML在线编辑工具 为了更好的.统一的编写统一简单易用的博客,决定采用TinyMCE工具.首先下载TinyMCE4.0包.文件目录如下: 其中, Plugins是插件目录,包括各种插件 ...

  5. angularjs 中通过 $location 进行路由跳转传参

    $location.path('/page1').search({id: $scope.id,name:$scope.name}); 带参数跳转页面,在新的页面通过$routeParams接收参数 $ ...

  6. 015 OS模块

    这个部分,也不是很难,就懒得写程序了,粘贴了一个不错的连接. 1.说明 os模块提供了多数操作系统的功能接口函数. 当os模块被导入后,它会自适应于不同的操作系统平台,根据不同的平台进行相应的操作,在 ...

  7. Python中GIL

    GIL(global interpreter lock)全局解释器锁 python中GIL使得同一个时刻只有一个线程在一个cpu上执行,无法将多个线程映射到多个cpu上执行,但GIL并不会一直占有,它 ...

  8. 使用soupUI做接口测试

    第一步:点击“file”,选择测试项目采用的协议:(这里我们测试的是http协议的,所以选择第三项)   第二步:在弹窗中输入测试项目的接口URL,并点击“OK”: 第三步:设置和填写请求项的内容并点 ...

  9. 如何让自己的Dev C++用上C++11,c++14标准

      首先确保Dev C++版本是最新的5.11版 其实用C++11和C++14标准的语法去运行还是会出现结果的,最多warning一下 但完美主义者是不允许这样的 我们可以点击菜单栏的“工具”-> ...

  10. 关于pycharm中安装第三方库时报错的解决办法(一)

    记录自己的生活!   一.事发背景 在pycharm中直接安装第三方库时因为版本问题总是无法安装成功,事情不大,但是很重要.   二.经过 最开始我自己电脑上安装了Python3.6和Python2. ...