您的位置:首页 > 大数据 > 人工智能

POJ 2010 Moo University - Financial Aid (优先队列)

2017-08-16 21:42 477 查看

题意:从C头奶牛中招收N(奇数)头。它们分别得分score_i,需要资助学费aid_i。希望新生所需资助不超过F,同时得分中位数最高。求此中位数。

思路:

先将奶牛排序,考虑每个奶牛作为中位数时,比它分数低(前面的)的那群牛的学费总和lower_i,后面的总和upper_i。然后从分数高往分数低扫描,满足aid_i + lower_i + upper_i <= F的第一个解就是最优解

#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
#define MAX_COW 100000 + 16

int N, C, F;
pair<int, int> cow[MAX_COW];
// 牛i作为中位数时,lower[i]表示分数低于它的牛的学费总和,upper[i]表示分数高于它的牛的学费总和
int lower[MAX_COW], upper[MAX_COW];

int main()
{
cin >> N >> C >> F;
int half = N / 2;
for (int i = 0; i < C; ++i)
{
cin >> cow[i].first >> cow[i].second;	// 分数  学费
}
sort(cow, cow + C);
{
int total = 0;
priority_queue<int> q;
for (int i = 0; i < C; ++i)
{
lower[i] = q.size() == half ? total : 0x3f3f3f3f;
q.push(cow[i].second);
total += cow[i].second;
if (q.size() > half)
{
// 踢掉一个学费最高的
total -= q.top(); q.pop();
}
}
}

{
int total = 0;
priority_queue<int> q;
for (int i = C - 1; i >= 0; --i)
{
upper[i] = q.size() == half ? total : 0x3f3f3f3f;
q.push(cow[i].second);
total += cow[i].second;
if (q.size() > half)
{
// 踢掉一个学费最高的
total -= q.top(); q.pop();
}
}
}

int result;
for (int i = C - 1; i >= 0; --i)
{
if (lower[i] + cow[i].second + upper[i] <= F)
{
result = cow[i].first;
break;
}
}
cout << result << endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: