奖学金

题目描述

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

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

输入格式

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

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

输出格式

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

输入输出样例

输入 #1

  1. 3 5 70
  2. 30 25
  3. 50 21
  4. 20 20
  5. 5 18
  6. 35 30

输出 #1

  1. 35

输入 #2

  1. 5 6 9
  2. 4 0
  3. 4 1
  4. 6 3
  5. 8 0
  6. 10 4
  7. 10 5

输出 #2

  1. 6

说明/提示

样例 1 解释

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

数据规模与约定

  1. 对于 30% 的数据,保证 n10^3c2×10^3
  2. 对于 100% 的数据,保证 3n10^5nc2×10^50f2×10^90ai2×10^9,0bi10^5

大致思路

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

代码实现

  1. #include <bits/stdc++.h>
  2. const int maxn=2e5+5;
  3. int n,c,F;
  4. std::priority_queue <int> q;
  5. struct Node{
  6. int s,w;//分数,奖金
  7. } a[maxn];
  8. bool cmp(const Node &a, const Node &b){
  9. return a.s<b.s;
  10. }
  11. int f[maxn],g[maxn],sum;;
  12. void Init(){
  13. scanf("%d%d%d", &n,&c,&F);
  14. for(int i=1;i<=c;++i)
  15. scanf("%d%d", &a[i].s,&a[i].w);
  16. std::sort(a+1,a+1+c,cmp);//按成绩升序
  17. }
  18. void Solve(){
  19. for(int i=1;i<=n/2;++i){//成绩最低的n/2进入队列
  20. sum+=a[i].w;//累加总奖金
  21. q.push(a[i].w);//队列是维护奖金的大根堆
  22. }
  23. //f[i]:表示以i为中位数前n/2人的最小奖金
  24. for(int i=n/2+1;i<=c;++i){
  25. f[i]=sum;
  26. int top=q.top();
  27. if(top>a[i].w){//如果当前的奖金小于堆顶则交换掉
  28. q.pop();
  29. sum-=top;
  30. sum+=a[i].w;
  31. q.push(a[i].w);
  32. }
  33. }
  34. sum=0;
  35. while(!q.empty()) q.pop();
  36. for(int i=c;i>=c-n/2+1;--i){//成绩最高的n/2进入队列
  37. sum+=a[i].w;
  38. q.push(a[i].w);
  39. }
  40. //g[i]:表示以i为中位数后n/2人的最低奖金
  41. for(int i=c-n/2;i>=1;--i){
  42. g[i]=sum;
  43. int top=q.top();
  44. if(top>a[i].w){//交换
  45. q.pop();
  46. sum-=top;
  47. sum+=a[i].w;
  48. q.push(a[i].w);
  49. }
  50. }
  51. //中位数的取值范围是[n/2+1,c-n/2]
  52. //因为要求最大中位数,所以倒序
  53. for(int i=c-n/2;i>=n/2+1;--i)
  54. if(a[i].w+f[i]+g[i]<=F){
  55. printf("%d", a[i].s);
  56. return;
  57. }
  58. printf("-1\n");
  59. }
  60. int main(){
  61. Init();
  62. Solve();
  63. return 0;
  64. }

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

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. Redis集群-主从模式

    1.架构设计 集群在单台主机上模拟搭建6个节点(3主3从的集群): 2.配置 创建与端口相同的文件夹存储Redis配置文件和持久化文件. 目录如下: 每个节点配置文件如下: 节点1: bind 192 ...

  2. 阻塞队列一——java中的阻塞队列

    目录 阻塞队列简介:介绍阻塞队列的特性与应用场景 java中的阻塞队列:介绍java中实现的供开发者使用的阻塞队列 BlockQueue中方法:介绍阻塞队列的API接口 阻塞队列的实现原理:具体的例子 ...

  3. iphone手机卡顿解决方案

    一.清除 safari缓存         设置->safari浏览器->清除历史记录与网站数据

  4. PAI-AutoLearning 图像分类使用教程

    概述 PAI AutoLearning(简称PAI AL)自动学习支持在线标注.自动模型训练.超参优化以及模型评估.在平台上只需准备少量标注数据,设置训练时长即可得到深度优化的模型.同时自动学习PAI ...

  5. sublime Text3 实现2:1:1三分屏效果

    小trick, 水一篇博客 先上效果图 由于写题啥的时候需要重定向输入输出改数据对拍, 设置成这样的效果就非常直观的看数据 直接切题, 首选项--快捷键--default里搜索alt+shift+1( ...

  6. WEditor(元素定位工具)安装和定位界面元素

     1. 安装adb(安装方法——百度网盘(无邪)) 2. 安装python-uiautomator2 pip install --pre -U uiautomator2 3. 手机设备安装atx-ag ...

  7. 使用numpy生成二维正态分布

    参考资料: https://www.zhihu.com/question/39823283?sort=created https://www.zhihu.com/question/288946037/ ...

  8. 使用LaTeX输入矩阵

    当前各种文本编辑器支持的LaTeX数学公式库大多基于KaTeX,或者在Web中用MathJax的比较多,下面给出一种在Web中输入矩阵的例子 $$\left[ \begin{array}{cccc}a ...

  9. python基础--函数全解析

    函数(重点) (1)初始函数 在认识函数之前,我们先做如下的需求: 让你打印10次"我爱中国,我爱祖国".我们在接触函数之前是这样写的. print('我爱中国,我爱祖国') pr ...

  10. VB.NET在基类中定义共享事件(类似于C#中的静态事件)

    基类: Public Class userFun Private Shared _PnlStatus As String ‘必须设为共享字段,如果不设为Shared,将不能传递字符串内容 Public ...