题解:P4952 [USACO04MAR] Financial Aid
一道贪心的题目。
我们通过样例分析就可以简化一下这道题其实就是让我们在
分析
首先我们可以先把这
具体实现
我们可以用一个大根堆,里面存当前的奶牛,如果出现了更优的奶牛,我们就可以把队首那个最差的奶牛踢出去,把更优的奶牛放入大根堆。举个例子,假设现在堆里有
AC 代码
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#define ll long long
using namespace std;
int n,c,f,ans=-1;
struct node{
int cast,money;
}a[100010];
int l[100010],r[100010];
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return f*x;
}
inline void write(int x) {
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
}
bool cmp(node a,node b){
return a.cast<b.cast;
}
int main(){
n=read(),c=read(),f=read();
for(int i=1;i<=c;i++){
a[i].cast=read(),a[i].money=read();
}
sort(a+1,a+1+c,cmp);
priority_queue<int>q;
int sum1=0,sum2=0;
int i;
for(i=1;i<=n/2;i++){//先将前n/2入堆
q.push(a[i].money);
sum1+=a[i].money;//当前的总和
}
for(i=n/2+1;i<=c-n/2;i++){
l[i]=sum1;
if(q.top()>a[i].money){//如果当前的比堆顶更优就进行替换
sum1-=q.top();
sum1+=a[i].money;
q.pop();
q.push(a[i].money);
}
}
priority_queue<int>p;//同理求R[i]
for(i=c;i>=c-n/2+1;i--){
p.push(a[i].money);
sum2+=a[i].money;
}
for(i=c-n/2;i>=n/2+1;i--){
r[i]=sum2;
if(p.top()>a[i].money){
sum2=sum2-p.top()+a[i].money;
p.pop();
p.push(a[i].money);
}
}
for(i=c-n/2;i>=n/2+1;i--){
if(l[i]+r[i]+a[i].money<=f){
printf("%d",a[i].cast);
return 0;
}
}
write(-1);
return 0;
}