【POJ - 2010】Moo University - Financial Aid(優先隊列)

Moo University - Financial Aid

Descriptionsios

奶牛大學:奶大招生,從C頭奶牛中招收N(N爲奇數)頭。它們分別得分score_i,須要資助學費aid_i。但願新生所需資助不超過F,同時得分中位數最高。求此中位數。spa

Input.net

*第1行:三個以空格分隔的整數N,C和F 

*第2..C + 1行:每行兩個以空格分隔的整數。首先是小牛的CSAT分數; 第二個整數是小牛所需的經濟援助金額 

Outputcode

*第1行:一個整數,即Bessie能夠達到的最大中位數分數。 若是沒有足夠的錢來接納N小牛,輸出-1。 

Sample Inputblog

3 5 70
30 25
50 21
20 20
5 18
35 30

Sample Output排序

35

Hintip

樣本輸出 若是Bessie接受CSAT分數爲5,35和50的小牛,則中位數爲35.所需的總經濟援助爲18 + 30 + 21 = 69 <= 70。 
 
題目連接
 
先將奶牛按分數排序,考慮每一個奶牛做爲中位數時,比它分數低(前面的)的那羣牛的學費總和lower_i,後面的總和upper_i。而後從分數高往分數低掃描,知足aid_i + lower_i + upper_i <= F的第一個解就是最優解。
 
AC代碼
#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>1
#include <cstring>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define Mod 1000000007
#define eps 1e-6
#define ll long long
#define INF 0x3f3f3f3f
#define MEM(x,y) memset(x,y,sizeof(x))
#define Maxn 100005
#define P pair<int,int>
using namespace std;
P a[Maxn];
int N,C,F;
// 牛i做爲中位數時,lower[i]表示分數低於它的牛的學費總和
int lower[Maxn],upper[Maxn];
int main()
{
    cin>>N>>C>>F;
    int half=N/2;
    for(int i=0; i<C; i++)
        cin>>a[i].first>>a[i].second; //分數  學費
    sort(a,a+C);
    {
        //求出lower[i]
        int total=0;
        priority_queue<int>q;
        for(int i=0; i<C; i++)
        {
            lower[i]=q.size()==half?total:INF;
            q.push(a[i].second);
            total+=a[i].second;
            if(q.size()>half)
            {
                //去掉一個學費最高的
                total-=q.top();
                q.pop();
            }
        }
    }
    {
        //求出upper[i]
        int total=0;
        priority_queue<int>q;
        for(int i=C-1; i>=0; i--)
        {
            upper[i]=q.size()==half?total:INF;
            q.push(a[i].second);
            total+=a[i].second;
            if(q.size()>half)
            {
                //去掉一個學費最高的
                total-=q.top();
                q.pop();
            }
        }
    }
    int ans=-1;
    for(int i=C-1; i>=0; i--)
        if(a[i].second+lower[i]+upper[i]<=F)
        {
            ans=a[i].first;
            break;
        }
    cout<<ans<<endl;
    return 0;
}
相關文章
相關標籤/搜索