转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove

骗一下访问量。。。。

题意大概是:从c个中选出n个,使得总花费小于等于f,保证价值的中位数最大

http://poj.org/problem?id=2010

做法:按价值排序之后,枚举中位数,然后对于小于中位数的部分贪心选出花费最小的n/2个,大于的部分也贪心选出花费最小的n/2个,然后比较总花费与f的关系。

可以用两个线段树维护一下,左部分便是每次insert一个,比较当前的第k小的大小,如果更小则remove掉原来的第k小,insert一个新的。

右部分便是每次remove一个,然后更新第k小。

#include <iostream>
#include <cmath>
#include <cstdio>
#include <algorithm>
#define lson step<<1
#define rson step<<1|1
#define LL long long
using namespace std;
const int N = 100005;
struct Node{
int cost,val;
bool operator<(const Node n)const{
return val<n.val;
}
}a[N];
struct Seg_tree{
int left,right;
int small,large;
}L[N<<2];
int m,n,f,x[N],tot;
LL Left=0,Right=0;
void bulid(int step,int l,int r){
L[step].left=l;
L[step].right=r;
L[step].small=L[step].large=0;
if(l==r) return ;
int m=(l+r)>>1;
bulid(lson,l,m);
bulid(rson,m+1,r);
}
void insert(int step,int pos,int kind){
if(!kind) L[step].small++;
else L[step].large++;
if(L[step].left==pos&&pos==L[step].right) return ;
int m=(L[step].left+L[step].right)>>1;
if(pos<=m) insert(lson,pos,kind);
else insert(rson,pos,kind);
}
int query(int step,int k,int kind){
if(L[step].left==L[step].right) return L[step].left;
int m=(L[step].left+L[step].right)>>1;
if(!kind){
if(L[lson].small>=k) return query(lson,k,kind);
else return query(rson,k-L[lson].small,kind);
}
else{
if(L[lson].large>=k) return query(lson,k,kind);
else return query(rson,k-L[lson].large,kind);
}
}
void remove(int step,int pos,int kind){
if(!kind) L[step].small--;
else L[step].large--;
if(L[step].left==L[step].right) return ;
int m=(L[step].left+L[step].right)>>1;
if(pos<=m) remove(lson,pos,kind);
else remove(rson,pos,kind);
}
int main(){
scanf("%d%d%d",&m,&n,&f);
for(int i=0;i<n;i++){
scanf("%d%d",&a[i].val,&a[i].cost);
x[i]=a[i].cost;
}
sort(a,a+n);
sort(x,x+n);
tot=unique(x,x+n)-x;
bulid(1,1,tot);
for(int i=0;i<m/2;i++){
Left+=(LL)a[i].cost;
int pos=lower_bound(x,x+tot,a[i].cost)-x+1;
insert(1,pos,0);
}
for(int i=m/2+1;i<n;i++){
int pos=lower_bound(x,x+tot,a[i].cost)-x+1;
if(i<m){
Right+=(LL)a[i].cost;
insert(1,pos,1);
}
else{
int idx=query(1,m/2,1);
if(a[i].cost<x[idx-1]) Right=Right-x[idx-1]+a[i].cost;
insert(1,pos,1);
}
}
int ans=-1;
for(int i=m/2;i<n-m/2;i++){
if((LL)Left+Right+a[i].cost<=f){
ans=max(ans,a[i].val);
}
int pos=lower_bound(x,x+tot,a[i].cost)-x+1;
int idx=query(1,m/2,0);
if(a[i].cost<x[idx-1]){
Left-=(LL)x[idx-1];
Left+=(LL)a[i].cost;
remove(1,idx,0);
insert(1,pos,0);
}
pos=lower_bound(x,x+tot,a[i+1].cost)-x+1;
remove(1,pos,1);
idx=query(1,m/2,1);
if(a[i+1].cost<x[idx-1]){
Right-=(LL)a[i+1].cost;
Right+=(LL)x[idx-1];
}
}
printf("%d\n",ans);
return 0;
}

poj 2010 Moo University - Financial Aid (贪心+线段树)的更多相关文章

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

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

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

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

  3. poj 2010 Moo University - Financial Aid

                                                                                                Moo Univ ...

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

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

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

    http://poj.org/problem?id=2010 "Moo U"大学有一种非常严格的入学考试(CSAT) ,每头小牛都会有一个得分.然而,"Moo U&quo ...

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

    考虑到数据结构短板严重,从计算几何换换口味= = 二叉堆 简介 堆总保持每个节点小于(大于)父亲节点.这样的堆被称作大根堆(小根堆). 顾名思义,大根堆的数根是堆内的最大元素. 堆的意义在于能快速O( ...

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

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

  8. POJ 2010 Moo University - Financial Aid treap

    按第一关键字排序后枚举中位数,就变成了判断“左边前K小的和 + 这个中位数 + 右边前K小的和 <= F",其中维护前K小和可以用treap做到. #include <cstdi ...

  9. POJ 2010 Moo University - Financial Aid 优先队列

    题意:给你c头牛,并给出每头牛的分数和花费,要求你找出其中n(n为奇数)头牛,并使这n头牛的分数的中位数尽可能大,同时这n头牛的总花费不能超过f,否则输出-1. 思路:首先对n头牛按分数进行排序,然后 ...

随机推荐

  1. 用c#实现单链表(程序代码已经验证,完全正确)

    1.程序的大致结构如下图: 2.下面依次列出各个类的代码 ①ILISTDs.cs  这是一个接口类,列出单链表的方法 using System; using System.Collections.Ge ...

  2. [LeetCode] Print All Combinations of a Number as a Sum of Candidate Numbers

    题目连接:http://leetcode.com/2010/09/print-all-combinations-of-number-as-sum.html 题目分析: 由于这里说明了输入是升序的,当然 ...

  3. javascript事件委托,事件代理,元素绑定多个事件之练习篇

    <ul id="parent-list"> <li id="post-1">item1</li> <li id=&qu ...

  4. C2B未来:大数据定制

    昨天看到微信SuperSofter写了一篇文章,有感而发.以便备记. 这是一种典型的C2B模式.阿里不仅仅是在与腾讯拼移动.它的电商本土业务也在稳步推进.近期一个里程碑事件是.阿里包下了美的.九阳.苏 ...

  5. 获取ocx运行路径的另一种方法

    在InitInstance里边可以获取   1 2 3 4 5 6 7 8 9 10 11 12     if (bInit)     {         // TODO: 在此添加您自己的模块初始化 ...

  6. Hibernate4读取Clob数据

    package cn.framework.dao.impl; import java.io.BufferedReader; import java.io.IOException; import jav ...

  7. iOS - NSLog的使用方法

    NSLog的定义 NSLog定义在NSObjCRuntime.h中,如下所示: void NSLog(NSString *format, …); 基本上,NSLog很像printf,同样会在conso ...

  8. VC 中与字符串相关的宏 _T、TEXT,_TEXT、L 的作用(简单明了)

    一. 在字符串前加一个L作用:    如  L"我的字符串"    表示将ANSI字符串转换成unicode的字符串,就是每个字符占用两个字节.   strlen("as ...

  9. (萌O(∩_∩)O)哈希知识点小结

    噶呜~先来了解一下什么是哈希吧? 当我们要在一堆东西中找到想要的那一个东西,我们常常通过比较来找,理想的情况是不经过任何比较,一次就能找到,怎么才能做到这样呢?那就在记录的储存位置和他的关键字之间建立 ...

  10. Facial Landmark Detection

    源地址:http://www.learnopencv.com/facial-landmark-detection/#comment-2471797375 OCTOBER 18, 2015 BY SAT ...