POJ2010--Moo University-Financial Aid(优先队列)

本文探讨了在有限预算下如何从一组牛中选择得分最高的中位数牛的算法,通过优先队列优化计算过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:从C头牛里选N头牛,每头牛有两个属性,得分score和经费aid,在总经费不超过F的情况下使得N头牛的得分中位数最大。

 

分析:先将C头牛按得分score升序,然后,我们假设每个i都可以作为中位数,lower[i]记录在i之前(也就是分数比它低)的总经费,upper[i]记录在i之后(也就是分数比它高)的总经费,最后,由于是求最大的中位数,所以,得分从后往前循环,第一个满足lower[i]+aid[i]+upper[i]的i就是最优解。

在求lower[i]和upper[i]的时候用优先队列把最大值弹出。


代码:

#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn = 111111;

pair<int, int> cow[maxn];
int lower[maxn], upper[maxn];

int main() {
    int n, c, f;
    while(~scanf("%d%d%d", &n, &c, &f)) {
        memset(lower, -1, sizeof(lower));
        memset(upper, -1, sizeof(upper));
        for(int i = 0; i < c; i++)
            scanf("%d%d", &cow[i].first, &cow[i].second);
        sort(cow, cow+c);
        int half = n/2;
        int tot = 0;
        priority_queue<int> pq;
        for(int i = 0; i < c; i++) {
            lower[i] = pq.size() == half ? tot : 1 << 30;
            pq.push(cow[i].second);
            tot += cow[i].second;
            if(pq.size() > half) {  //去掉经费最多的
                tot -= pq.top();
                pq.pop();
            }
        }
        tot = 0;
        while(!pq.empty()) {pq.pop();}
        for(int i = c-1; i >= 0; i--) {
            upper[i] = pq.size() == half ? tot : 1 << 30;
            pq.push(cow[i].second);
            tot += cow[i].second;
            if(pq.size() > half) {  //去掉经费最多的
                tot -= pq.top();
                pq.pop();
            }
        }
        int ans = -1;
        for(int i = c-1; i >= 0; i--) {
            if(lower[i] + cow[i].second + upper[i] <= f) {
                ans = cow[i].first;
                break;
            }
        }
        printf("%d\n", ans);
        while(!pq.empty()) {pq.pop();}
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值