POJ 2010 (优先队列
用优先队列扫一次得到大于和小于中位数的总和的最小值,再扫一遍得到最优解
#include<iostream> #include<cstdio> #include<algorithm> #include<queue> #include<utility> #include<vector> #define INF 0x3fffffff using namespace std; typedef long long ll; int N,C,F; typedef pair<int,int> pii; const int maxv=1e5+30; pair<int,int> cow[maxv];////score,aid ll low[maxv],upp[maxv]; bool cmp(pii a,pii b){ return a.second<b.second; } int main(){ freopen("in.txt","r",stdin); cin>>N>>C>>F; for(int i=0;i<C;i++) scanf("%d%d",&cow[i].first,&cow[i].second); sort(cow,cow+C); ll tol=0; priority_queue<int> Q1,Q2; ll half=N/2; for(int i=0;i<C;i++){ low[i]=(Q1.size()==half?tol:INF); Q1.push(cow[i].second); tol+=cow[i].second; if(Q1.size()>half){ tol-=Q1.top(); Q1.pop(); } } tol=0; for(int i=C-1;i>=0;i--){ upp[i]=(Q2.size()==half?tol:INF); Q2.push(cow[i].second); tol+=cow[i].second; if(Q2.size()>half){ tol-=Q2.top(); Q2.pop(); } } int ans=-1; for(int i=0;i<C;i++){ if(low[i]+upp[i]+cow[i].second<=F) ans=cow[i].first; } cout<<ans<<endl; return 0; }