奖学金

题目描述

小张学院有 \(c\) 名学生,第 \(i\) 名学生的成绩为 \(ai\) ​,要获得的奖学金金额为 \(bi\) 。

要从这 \(c\) 名学生中挑出 \(n\) 名学生发奖学金。这个神秘人物爱好奇特,他希望得到奖学金的同学的成绩的中位数尽可能大,但同时,他们的奖学金总额不能超过 \(f\) 。

输入格式

第一行有三个整数,分别表示要挑出的学生人数 \(n\) ,学生总人数 \(c\) 和奖学金总额的最大值 \(f\) 。

第 \(2\) 到第 \((c+1)\) 行,每行两个整数,第 \((i+1)\) 行的整数依次表示第 \(i\) 名学生的成绩 \(ai\)​ 和如果要给他发奖学金,则需要发的金额数 \(bi\) ​。

输出格式

输出一行一个整数表示答案。如果无法满足神秘人的条件,请输出 \(−1\) 。

输入输出样例

输入 #1

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

输出 #1

35

输入 #2

5 6 9
4 0
4 1
6 3
8 0
10 4
10 5

输出 #2

6

说明/提示

样例 1 解释

选择成绩为 \(5\) , \(35\) , \(50\) 的三名同学,奖金总额为 \(18+30+21=69\)。

数据规模与约定

对于 30% 的数据,保证 n≤10^3,c≤2×10^3。
对于 100% 的数据,保证 3≤n≤10^5,n≤c≤2×10^5,0≤f≤2×10^9,0≤ai≤2×10^9,0≤bi≤10^5。

大致思路

首先要保证这道题要求中位数的最大值,那么就是尽可能的放成绩尽可能最高的那个,首先用\(sort\)根据成绩来排序,一个堆把前\((n+1)/2\)的数放进大跟堆里,然后从\((n+1)/2\)开始\(for\)循环来一次枚举成绩高的,要是成绩高而且奖学金需求还比大跟堆里最大的金额少,那么一定要放进去,并把价格最高的踢出来,保证刚放进去的数是第\((n+1)/2\)个数,直到搜到第\(c-(n+1)/2\)的时候,停止,维护了当前形式的最大中位数,再从后\((n+1)/2\)个数里向前走,求出当前形式的最小中位数,然后跑一个\(for\)循环来求出最大的中位数即可。

代码实现

#include <bits/stdc++.h>
const int maxn=2e5+5;
int n,c,F;
std::priority_queue <int> q;
struct Node{
int s,w;//分数,奖金
} a[maxn];
bool cmp(const Node &a, const Node &b){
return a.s<b.s;
}
int f[maxn],g[maxn],sum;;
void Init(){
scanf("%d%d%d", &n,&c,&F);
for(int i=1;i<=c;++i)
scanf("%d%d", &a[i].s,&a[i].w);
std::sort(a+1,a+1+c,cmp);//按成绩升序
}
void Solve(){
for(int i=1;i<=n/2;++i){//成绩最低的n/2进入队列
sum+=a[i].w;//累加总奖金
q.push(a[i].w);//队列是维护奖金的大根堆
}
//f[i]:表示以i为中位数前n/2人的最小奖金
for(int i=n/2+1;i<=c;++i){
f[i]=sum;
int top=q.top();
if(top>a[i].w){//如果当前的奖金小于堆顶则交换掉
q.pop();
sum-=top;
sum+=a[i].w;
q.push(a[i].w);
}
} sum=0;
while(!q.empty()) q.pop();
for(int i=c;i>=c-n/2+1;--i){//成绩最高的n/2进入队列
sum+=a[i].w;
q.push(a[i].w);
}
//g[i]:表示以i为中位数后n/2人的最低奖金
for(int i=c-n/2;i>=1;--i){
g[i]=sum;
int top=q.top();
if(top>a[i].w){//交换
q.pop();
sum-=top;
sum+=a[i].w;
q.push(a[i].w);
}
}
//中位数的取值范围是[n/2+1,c-n/2]
//因为要求最大中位数,所以倒序
for(int i=c-n/2;i>=n/2+1;--i)
if(a[i].w+f[i]+g[i]<=F){
printf("%d", a[i].s);
return;
}
printf("-1\n");
}
int main(){
Init();
Solve();
return 0;
}

代码是教练员的,自己码风有一..恶心

TJOI2013 奖学金—大根堆实现(洛谷P3963)的更多相关文章

  1. 模板 可并堆【洛谷P3377】 【模板】左偏树(可并堆)

    P3377 [模板]左偏树(可并堆) 如题,一开始有N个小根堆,每个堆包含且仅包含一个数.接下来需要支持两种操作: 操作1: 1 x y 将第x个数和第y个数所在的小根堆合并(若第x或第y个数已经被删 ...

  2. 堆学习笔记(未完待续)(洛谷p1090合并果子)

    上次讲了堆,别人都说极其简单,我却没学过,今天又听dalao们讲图论,最短路又用堆优化,问懂了没,底下全说懂了,我???,感觉全世界都会了堆,就我不会,于是我决定补一补: ——————来自百度百科 所 ...

  3. 洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心)

    洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/132 ...

  4. 洛谷P3377 【模板】左偏树(可并堆) 题解

    作者:zifeiy 标签:左偏树 这篇随笔需要你在之前掌握 堆 和 二叉树 的相关知识点. 堆支持在 \(O(\log n)\) 的时间内进行插入元素.查询最值和删除最值的操作.在这里,如果最值是最小 ...

  5. 洛谷 P3377 【模板】左偏树(可并堆)

    洛谷 P3377 [模板]左偏树(可并堆) 题目描述 如题,一开始有N个小根堆,每个堆包含且仅包含一个数.接下来需要支持两种操作: 操作1: 1 x y 将第x个数和第y个数所在的小根堆合并(若第x或 ...

  6. 洛谷.5283.[十二省联考2019]异或粽子(可持久化Trie 堆)

    LOJ 洛谷 考场上都拍上了,8:50才发现我读错了题=-= 两天都读错题...醉惹... \(Solution1\) 先求一遍前缀异或和. 假设左端点是\(i\),那么我们要在\([i,n]\)中找 ...

  7. 洛谷 P4272 - [CTSC2009]序列变换(堆)

    洛谷题面传送门 u1s1 在我完成这篇题解之前,全网总共两篇题解,一篇使用的平衡树,一篇使用的就是这篇题解讲解的这个做法,但特判掉了一个点,把特判去掉在 BZOJ 上会 WA 一个点. 两篇题解都异常 ...

  8. 2018.07.31洛谷P1552 [APIO2012]派遣(可并堆)

    传送门 貌似是个可并堆的模板题,笔者懒得写左偏堆了,直接随机堆水过.实际上这题就是维护一个可合并的大根堆一直从叶子合并到根,如果堆中所有数的和超过了上限就一直弹直到所有数的和不超过上限为止,最后对于当 ...

  9. 【洛谷】【treap/堆】P2073 送花

    [题目描述:] 这些花都很漂亮,每朵花有一个美丽值W,价格为C. 小明一开始有一个空的花束,他不断地向里面添加花.他有以下几种操作: 操作 含义 1 W C 添加一朵美丽值为W,价格为C的花. 3 小 ...

随机推荐

  1. 密码学DAY1_02

    目录 1.1 ASCII编码 1.2 凯撒加密 1.2.1 中国古代加密 1.2.2 外国加密 1.2.3 凯撒位移加密--JAVA代码实现 1.2.4 频度分析法破解恺撒加密 1.3现代常用的加密方 ...

  2. 用js实现简单的抛物线运动

    前言 老早就看过一些购物车的抛物线效果,也想自己凑热闹动手来实现一遍. 然后(lll¬ω¬) 书到用时方恨少,发现高中学到物理啊.数学啊,都忘光了,抛物线公式都忘了0 0. 顺手百度一波,从百度可知: ...

  3. yum安装配置MySQL数据库

    1.配置yum源 # 先安装wget yum install wget -y     2.下载mysql源安装包 wget http://dev.mysql.com/get/mysql57-commu ...

  4. CoordinatorLayout简介

    CoordinatorLayout简介 CoordinatorLayout的作用 协调子view的布局,降低子view之间的耦合度 CoordinatorLayout的使用 核心:Behavior,用 ...

  5. Ubuntu16.04安装完成后首先更换源地址,加速下载

    也可以,sudo pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple临时改变源地址下载先备份源文件sudo cp sources ...

  6. php的ts和nts选择

    TS(Thread-Safety)即线程安全,多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用.不会出现数据不一致或者数据 ...

  7. 【loj - 3056】 「HNOI2019」多边形

    目录 description solution accepted code details description 小 R 与小 W 在玩游戏. 他们有一个边数为 \(n\) 的凸多边形,其顶点沿逆时 ...

  8. 排队I(替换两层复杂for循环、避免TLE)

    问题 C: 排队I(点击) 时间限制: 1 Sec  内存限制: 128 MB                                                             ...

  9. Mybatis源码手记-从缓存体系看责任链派发模式与循环依赖企业级实践

    一.缓存总览 Mybatis在设计上处处都有用到的缓存,而且Mybatis的缓存体系设计上遵循单一职责.开闭原则.高度解耦.及其精巧,充分的将缓存分层,其独到之处可以套用到很多类似的业务上.这里将主要 ...

  10. 深入理解Java虚拟机学习笔记(二)-----垃圾收集器与内存分配策略

    写在前面 本节常见面试题: 如何判断对象是否死亡(两种方法). 简单的介绍一下强引用.软引用.弱引用.虚引用(虚引用与软引用和弱引用的区别.使用软引用能带来的好处). 如何判断一个常量是废弃常量 如何 ...