【题解】洛谷 P4952 【[USACO 2004 Mar]Financial Aid 赞助学费】——中位数

本文介绍了一种解决特定中位数问题的方法,通过将牛的分数排序,并使用大根堆来确定符合条件的最大中位数成绩。算法首先计算左侧和右侧的最小总费用,然后找出满足预算条件的最大分数。
摘要由CSDN通过智能技术生成

这显然是一道关于中位数的水题。

那么简化问题及为:

要求选出的N头牛的成绩的中位数尽可能大,我们可以考虑依次讨论每头奶牛的成绩是否适合作为中位数。

1.先把牛们的分数由小到大排序

那么这个中位数显然在[n/2+1…c-n/2]中。

2.若k位于这个范围[n/2+1…c-n/2],那么Score[k]是否是一个合理的中位数呢?

在[1…k-1]间定要选出n/2头牛,我们希望选总学费尽量少n/2头奶牛,设该学费总额为Left[k](left[k]表示在k这头牛左边满足n/2头牛的钱的最小的总和,right同理)

在[k+1…c]间定也要选出n/2头牛,我们也希望选总学费尽量少n/2头奶牛,设该学费总额为Right[k]

如果满足left[k]+right[k]+money[k]<=F

那么这就是一种合理的情况

最终找出满足条件 Left[k]+Right[k]+Money[k]<=F 的最大的一个k,它对应的Score[k]即为答案。

3.求[n/2+1…c-n/2]中每个数对应的left[ ]和right[ ]

建立一个大根堆,把最左边的n/2头牛所要的费用存到堆里面,用sum记下总和。
设当前讨论到了第k头牛

if(money[k]<堆顶元素)就用money[k]把堆顶元素换掉

继续讨论下一头牛


right[ ]的求法同left[ ]!

AC代码


#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
struct node{int fen,money,left,right;}cow[100005];
int C,N,F;
priority_queue<int>q;
bool cmp(node a,node b){return a.fen==b.fen?a.money<b.money:a.fen<b.fen;}
void init(){
	scanf("%d%d%d",&N,&C,&F);
	for(int i=1;i<=C;i++)scanf("%d%d",&cow[i].fen,&cow[i].money);
	sort(cow+1,cow+1+C,cmp); //先要排序
}
void LEFT(){//左边
	int sum=0;
	for(int i=1;i<=N/2;i++){
		q.push(cow[i].money);
		sum+=cow[i].money;
	}//最左边的
	for(int i=N/2+1;i<=C-N/2;i++){
		int t=q.top();
		cow[i].left=sum;
		if(cow[i].money<t){
			q.pop();
			sum=sum-t+cow[i].money;
			q.push(cow[i].money);
		}
	}
	while(!q.empty())q.pop();
}
void RIGHT(){//右边
	int sum=0;
	for(int i=C;i>=C-N/2+1;i--){
		q.push(cow[i].money);
		sum+=cow[i].money;
	}//最右边的
	for(int i=C-N/2;i>=N/2+1;i--){
		int t=q.top();
		cow[i].right=sum;
		if(cow[i].money<t){
			q.pop();
			sum=sum-t+cow[i].money;
			q.push(cow[i].money);
		}//互换
	}
}
int main(){
	int ans=-1;//赋值为-1
	init();
	LEFT();
	RIGHT();
	for(int i=C-N/2;i>=N/2+1;i--){
		if(cow[i].left+cow[i].right+cow[i].money<=F){
			ans=cow[i].fen;
			break;
		}
	}
	printf("%d",ans);
}


内容概要:该题库专为研究生入学考试计算机组成原理科目设计,涵盖名校考研真题、经典教材课后习题、章节题库和模拟试题四大核心模块。名校考研真题精选多所知名高校的计算机组成原理科目及计算机联考真题,并提供详尽解析,帮助考生把握考研命题趋势与难度。经典教材课后习题包括白中英《计算机组成原理》(第5版)和唐朔飞《计算机组成原理》(第2版)的全部课后习题解答,这两部教材被众多名校列为考研指定参考书目。章节题库精选代表性考题,注重基础知识与重难点内容,帮助考生全面掌握考试大纲要求的知识点。模拟试题依据历年考研真题命题规律和热门考点,精心编制两套全真模拟试题,并附标准答案,帮助考生检验学习成果,评估应试能力。 适用人群:计划参加研究生入学考试并报考计算机组成原理科目的考生,尤其是需要系统复习和强化训练的学生。 使用场景及目标:①通过研读名校考研真题,考生可以准确把握考研命题趋势与难度,有效评估复习成效;②通过经典教材课后习题的练习,考生可以巩固基础知识,掌握解题技巧;③通过章节题库的系统练习,考生可以全面掌握考试大纲要求的各个知识点,为备考打下坚实基础;④通过模拟试题的测试,考生可以检验学习成果,评估应试能力,为正式考试做好充分准备。 其他说明:该题库不仅提供详细的题目解析,还涵盖了计算机组成原理的各个方面,包括计算机系统概述、数据表示与运算、存储器分层、指令系统、中央处理器、总线系统和输入输出系统等。考生在使用过程中应结合理论学习与实践操作,注重理解与应用,以提高应试能力和专业知识水平。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

go_bananas

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值