TJOI2013 奖学金—大根堆实现(洛谷P3963)
奖学金
题目描述
小张学院有 \(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)的更多相关文章
- 模板 可并堆【洛谷P3377】 【模板】左偏树(可并堆)
		
P3377 [模板]左偏树(可并堆) 如题,一开始有N个小根堆,每个堆包含且仅包含一个数.接下来需要支持两种操作: 操作1: 1 x y 将第x个数和第y个数所在的小根堆合并(若第x或第y个数已经被删 ...
 - 堆学习笔记(未完待续)(洛谷p1090合并果子)
		
上次讲了堆,别人都说极其简单,我却没学过,今天又听dalao们讲图论,最短路又用堆优化,问懂了没,底下全说懂了,我???,感觉全世界都会了堆,就我不会,于是我决定补一补: ——————来自百度百科 所 ...
 - 洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心)
		
洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/132 ...
 - 洛谷P3377 【模板】左偏树(可并堆) 题解
		
作者:zifeiy 标签:左偏树 这篇随笔需要你在之前掌握 堆 和 二叉树 的相关知识点. 堆支持在 \(O(\log n)\) 的时间内进行插入元素.查询最值和删除最值的操作.在这里,如果最值是最小 ...
 - 洛谷 P3377 【模板】左偏树(可并堆)
		
洛谷 P3377 [模板]左偏树(可并堆) 题目描述 如题,一开始有N个小根堆,每个堆包含且仅包含一个数.接下来需要支持两种操作: 操作1: 1 x y 将第x个数和第y个数所在的小根堆合并(若第x或 ...
 - 洛谷.5283.[十二省联考2019]异或粽子(可持久化Trie 堆)
		
LOJ 洛谷 考场上都拍上了,8:50才发现我读错了题=-= 两天都读错题...醉惹... \(Solution1\) 先求一遍前缀异或和. 假设左端点是\(i\),那么我们要在\([i,n]\)中找 ...
 - 洛谷 P4272 - [CTSC2009]序列变换(堆)
		
洛谷题面传送门 u1s1 在我完成这篇题解之前,全网总共两篇题解,一篇使用的平衡树,一篇使用的就是这篇题解讲解的这个做法,但特判掉了一个点,把特判去掉在 BZOJ 上会 WA 一个点. 两篇题解都异常 ...
 - 2018.07.31洛谷P1552 [APIO2012]派遣(可并堆)
		
传送门 貌似是个可并堆的模板题,笔者懒得写左偏堆了,直接随机堆水过.实际上这题就是维护一个可合并的大根堆一直从叶子合并到根,如果堆中所有数的和超过了上限就一直弹直到所有数的和不超过上限为止,最后对于当 ...
 - 【洛谷】【treap/堆】P2073 送花
		
[题目描述:] 这些花都很漂亮,每朵花有一个美丽值W,价格为C. 小明一开始有一个空的花束,他不断地向里面添加花.他有以下几种操作: 操作 含义 1 W C 添加一朵美丽值为W,价格为C的花. 3 小 ...
 
随机推荐
- 关于uniapp获取当前距离屏幕顶部的距离
			
onPageScroll(e){ console.log(e); }
 - Java 技术网站总结(不停更新)
			
Spring Spring 中文手册 Spring 教程 Spring For All Spring 学习笔记 Spring Boot Break易站 Spring Cloud 中文文档 Spring ...
 - Rectangle【思维+模拟】
			
Rectangle 题目链接(点击) frog has a piece of paper divided into nn rows and mm columns. Today, she would l ...
 - Proving Equivalences(缩点+有环图变强连通分量)【tarjian算法】
			
Proving Equivalences 题目链接(点击) 参考博客(点击) Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768 ...
 - tomcat的安装部署(windows10)
			
一.Tomact下载 地址:https://tomcat.apache.org/
 - Android中的SharedPreferences存储
			
一.前言 不同于文件的存储方式,SharedPreferences是使用键值对的方式来存储数据的.也就是说,当保存一条数据的时候,需要给这条数据提供一个对应的键,这样在读取数据的时候就可以通过这个键把 ...
 - 10 种常用 Matplotlib 图的 Python 代码
			
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 喜欢的朋友欢迎关注小编,除了分享技术文章之外还有很多福利,私信“资料”可以 ...
 - 学员操作——制作5s关闭广告
			
<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>广 ...
 - 记一次uboot升级过程的两个坑
			
背景 之前做过一次uboot的升级,当时留下了一些记录,本文摘录其中比较有意思的两个问题. 启动失败问题 问题简述 uboot代码中用到了一个库,考虑到库本身跟uboot版本没什么关系,就直接把旧的库 ...
 - [ 头皮发麻 A1 ]  队内赛3 2020 Ateneo de Manila University DISCS PrO HS Division
			
都是英语阅读题 但是本菜鸡就过了一题,直接自闭mmp明天开始起床一版题 传送门 B.Riana and the Blind Date 0是闰年?惊了 后来才知道整除被除数可以为0 闰年的计算方法 \( ...