Financial Aid POJ
阿新 • • 發佈:2018-12-12
題意:奶牛大學為了使得學生選出來的分數中位數最高,並且所選的學生所需的贊助還不能超出預估
題解:首先將所有學生的成績從小到大排序,然後使用優先佇列求出每個位上左邊所要N/2個學生時所需的最小贊助,右邊所要N/2個學生時所需的最小贊助,最後逆序列舉該位上的f1[i]+p[i].c+f2[i]<=F,一旦滿足,直接跳出即可,這個即是滿足條件的答案。
附上程式碼:
#include<iostream> #include<cstdio> #include<algorithm> #include<queue> #include<cstring> using namespace std; const int maxn=100010; int N,C,F; struct node{ int s,c; friend bool operator < (node a,node b){ return a.c<b.c; } }; node p[maxn]; bool cmp(node a,node b) { return a.s<b.s; } priority_queue<node>q1,q2; int f1[maxn],f2[maxn]; void solve() { sort(p,p+C,cmp); int sum1=0,sum2=0; int ans=-1; memset(f1,0,sizeof(f1)); memset(f2,0,sizeof(f2)); for(int i=0;i<C;i++){ if(i<N/2){ q1.push(p[i]); sum1+=p[i].c; continue; } f1[i]=sum1; if(p[i].c>=q1.top().c){ continue; } sum1-=q1.top().c; q1.pop(); sum1+=p[i].c; q1.push(p[i]); } for(int i=C-1;i>=0;i--){ if(i>C-1-N/2){ q2.push(p[i]); sum2+=p[i].c; continue; } f2[i]=sum2; if(p[i].c>=q2.top().c){ continue; } sum2-=q2.top().c; q2.pop(); sum2+=p[i].c; q2.push(p[i]); } for(int i=C-1-N/2;i>=N/2;i--){ if(f1[i]+f2[i]+p[i].c<=F){ ans=p[i].s; break; } } printf("%d\n",ans); } int main() { while(~scanf("%d%d%d",&N,&C,&F)){ for(int i=0;i<C;i++){ scanf("%d%d",&p[i].s,&p[i].c); } solve(); } return 0; }