题意:
有个学校,从c个学生中挑n个学生,要求每个学生的资助金总和<=f
求符合条件的选择方案中中学生成绩中位数的最大值
题解:
有一个lower数组,记录当第i个人是中位数时候,前面的人所需要的资金的最小值,同理有一个upper数组
lower[i] = q.size() == half ? total : 0x3f3f3f3f;
total是当前最小值
if (q.size() > half)
{
total -= q.top(); q.pop();
}
因为这句话保证了当前最小
#include <iostream>
#include <algorithm>
#include <queue>
#include<stdio.h>
#include<string.h>
using namespace std;
#define MAX_COW 100000 + 16
int N, C;
long long F;
pair<int, int> cow[MAX_COW];
int lower[MAX_COW], upper[MAX_COW];
int main()
{
cin >> N >> C >> F;
int half = N / 2;
for (int i = 0; i < C; ++i)
{
scanf("%d%d",&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 = -1;
for (int i = C - 1; i >= 0; --i)
{
if (lower[i] + cow[i].second + upper[i] <= F)
{
result = cow[i].first;
break;
}
}
printf("%d\n",result);
return 0;
}