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