Description
Input
Output
Sample Input
3 5 70 30 25 50 21 20 20 5 18 35 30
Sample Output
35
Hint
题意:给你 c头牛和每头牛的智商、花费,要你选择 n头牛使这 n头牛智商的中位数最大,前提是花费总和不能超过 f
题解:先对每头牛的智商从小到大排序,然后枚举智商的中位数,对于某个中位数i,左边和右边各取花费最小的n/2头牛。怎么取呢?先用优先队列预处理每头牛左右两边n/2头牛花费最小值即可。
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <map>
#include <vector>
#include <list>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <algorithm>
#include <functional>
#include <iomanip>
#include <limits>
#include <new>
#include <utility>
#include <iterator>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <ctime>
using namespace std;
const int maxn = 100010;
priority_queue<int> p, q;
int n, c, f;
pair<int, int> cow[maxn];
int l[maxn], r[maxn];
int main()
{
cin >> n >> c >> f;
for (int i = 0; i < c; ++i)
scanf("%d%d", &cow[i].first, &cow[i].second);
sort(cow, cow+c);
//预处理以i为中位数时左边n/2头牛花费的最小值
int s = 0;
for (int i = 0; i < c; ++i)
{
if (p.size() == n / 2)
l[i] = s;
p.push(cow[i].second);
s += cow[i].second;
if (p.size() > n / 2)
{
s -= p.top();
p.pop();
}
}
//预处理以i为中位数时右边n/2头牛花费的最小值
s = 0;
for (int i = c-1; i >= 0; --i)
{
if (q.size() == n / 2)
r[i] = s;
q.push(cow[i].second);
s += cow[i].second;
if (q.size() > n / 2)
{
s -= q.top();
q.pop();
}
}
//从大到小枚举中位数,满足题意就退出
for (int i = c-(n+1)/2; i >= n/2; --i)
{
int sum = cow[i].second + l[i] + r[i];
if (sum <= f)
{
cout << cow[i].first << endl;
return 0;
}
}
cout << "-1" << endl;
return 0;
}
版权声明:本文为博主原创文章,转载请注明出处。
poj2010(Moo University - Financial Aid)优先队列
原文地址:http://blog.csdn.net/god_weiyang/article/details/47752259