题意:

在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. react react-transition-group实现动画

    import React,{ Component,Fragment } from 'react';import './style.css';import { CSSTransition,Transit ...

  2. [转] Javascript模块化编程(一):模块的写法

    随着网站逐渐变成"互联网应用程序",嵌入网页的Javascript代码越来越庞大,越来越复杂. 网页越来越像桌面程序,需要一个团队分工协作.进度管理.单元测试等等......开发者 ...

  3. [转] 深入浅出mongoose-----包括mongoose基本所有操作,非常实用!!!!!

    深入浅出mongoose mongoose是nodeJS提供连接 mongodb的一个库. 此外还有mongoskin, mongodb(mongodb官方出品). 本人,还是比较青睐mongoose ...

  4. CGAffineTransform的使用

    typedef struct CGAffineTransform CGAffineTransform; struct CGAffineTransform { CGFloat a, b, c, d; C ...

  5. nginx 设置自签名证书以及设置网址http强制转https访问

    自签名证书可以在自己的内网环境或者非对外环境使用,保证通信安装 1.生产证书 直接使用脚本生产: 中途会提示书如1次域名和4次密码,把一下文件保存为sh文件,赋予x权限后 直接执行,根据提示输入. # ...

  6. 【AtCoder】ARC075

    ARC075 在省选前一天听说正式选手线画到省二,有了别的女选手,慌的一批,然后刷了一个ARC来稍微找回一点代码感觉 最后还是挂分了,不开心 果然水平退化老年加重啊 原题链接 C - Bugged 直 ...

  7. 如何访问https的网站?-【httpclient】

    备注:本处代码使用groovy和httpclient4.3作为例子进行讲述 在普通方式下,当使用httpclient进行访问某个网站时,大致使用如下的代码进行访问: CloseableHttpClie ...

  8. cmake与autoconf+automake

    cmake与autoconf+automakes是同类的编译工具,本人常用的是cmake. 这有一篇对比的文章,记录一下. cmake与autoconf+automake的对比

  9. PHP页面间传值的几种方法

    方法一:require_once //Page a: <?php $a = "hello"; ?> //Page b: <?php require_once &q ...

  10. HTML5上传图片预览功能

    HTML5上传图片预览功能 HTML代码如下: <!-- date: 2018-04-27 14:41:35 author: 王召波 descride: HTML5上传图片预览功能 --> ...