[TJOI2013]奖学金 乱搞
2024-08-27 11:03:16
[TJOI2013]奖学金 乱搞
从\(c\)个二元组\((v,w)\)中选出\(n\)个,使其\(v\)的中位数最大的同时使\(w\)和小于等于\(f\),求这个中位数
有点意思。有点像二分答案的思路,枚举中位数,将原问题转换为一个判定问题,贪心选择中位数之前\(w\)最小的\((n-1)/2\)个,之后\(w\)最小的\((n-1)/2\)个,然后判断一下是否小于等于\(f\)即可。
使用优先队列贪心即可。
#include <cstdio>
#include <algorithm>
#include <queue>
#define MAXN 200002
using namespace std;
int n,c,mx;
priority_queue <int> q;
struct nod{
int s,w;
} a[MAXN];
bool cmp(const nod &a, const nod &b){
return a.s<b.s;
}
int sum;
int f[MAXN],g[MAXN];
int main(){
scanf("%d %d %d", &n, &c, &mx);
for(int i=1;i<=c;++i)
scanf("%d %d", &a[i].s, &a[i].w);
sort(a+1, a+1+c, cmp);
for(int i=1;i<=n/2;++i){
sum+=a[i].w;
q.push(a[i].w);
}
//f[i] <i min cost
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){
sum+=a[i].w;
q.push(a[i].w);
}
//g[i] >i min cost
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);
}
}
for(int i=c-n/2;i>=n/2+1;--i)
if(a[i].w+f[i]+g[i]<=mx){
printf("%d", a[i].s);
return 0;
}
puts("-1");
return 0;
}
最新文章
- HDU4010 (动态树)
- BZOJ4657 : tower
- Same Tree [LeetCode]
- Java SE (1)之 JFrame 组件 GridLayout布局
- ExtJS简单的动画效果2(ext js淡入淡出特效)
- HDOJ(HDU) 2143 box(简单的多次判断-用的卫条件)
- BZOJ 1497: [NOI2006]最大获利( 最大流 )
- elk 5.x的部署
- js模拟form表单提交数据, js模拟a标签点击跳转,避开使用window.open引起来的浏览器阻止问题
- 测试APPEND INSERT是否产生UNDO信息的过程
- window.loaction.href 不自动跳转的问题
- tiny png
- SQL SERVER GO命令循环使用实例
- ccf--20140903--字符串匹配
- pyqt信号和槽传递额外参数
- linux-ubuntu 安装配置Redis
- 使用Visual VM 查看linux中tomcat运行时JVM内存
- vue之常用指令
- SpringMVC学习笔记二第一个小的程序
- POI的简单使用