POJ 2010 Moo University

按照score排序,贪心,从左到右用堆维护并且记录前面的最小N/2个花费之和。

然后从右向左枚举中位数,维护N/2个数之和加上并判断是否满足条件。(stl的队列没有clear(),只能一个一个pop...

复杂度O(nlogn) 

也可以二分。先按照score排序,记录备份牛在排序后的下标。然后将备份按照资金排序,

,二分中位数的值,对于mid值,按照备份顺序贪心选择牛,根据之前的下标判断在左边或者右边。

因为是最贪心的选,如果两边都不够,说明无解。如果某一边少了,mid就应该往相反的方向移动。

如果满足条件就记录答案,并向上缩小区间。

复杂度也是O(nlogn)

#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<queue>
#include<vector>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
//#include<bits/stdc++.h>
using namespace std;

#define PB push_back
#define MP make_pair
#define fi first
#define se second
#define PS push

const int maxn = 1e5+5;
const int maxsz = 1e4+5;
struct BinaryHEAP
{
    int Heap[maxsz];
    int sz;
    #define Cmp(a,b) ((a)>(b))
    void push(int x)
    {
        int i = ++sz;
        while(i > 1){
            int p = i>>1;
            if(!Cmp(x,Heap[p])) break;
            Heap[i] = Heap[p];
            i = p;
        }
        Heap[i] = x;
    }

    void pop()
    {
        int x = Heap[sz--];
        int i = 1;
        while((i<<1)<=sz){
            int a = i<<1, b = i<<1|1;
            if(b<=sz && Cmp(Heap[b],Heap[a])) a = b;
            if(!Cmp(Heap[a],x)) break;
            Heap[i] = Heap[a];
            i = a;
        }
        Heap[i] = x;
    }
    int top(){ return Heap[1]; }
    //int operator[](int x){ return Heap[x]; }
}q;

pair<int,int> cow[maxn];
int N, C, F;
int Half;
int preSum[maxn];


int sol()
{
    sort(cow,cow+C);
    int Half = N>>1, sum = 0;
    for(int i = 0; i < Half; i++) {
        sum += cow[i].se;
        q.push(cow[i].se);
    }
    for(int i = Half; i < C-Half; i++){
        preSum[i] = sum;
        if(q.top() > cow[i].se) {
            sum -= q.top();
            q.pop();
            sum += cow[i].se;
            q.push(cow[i].se);
        }

    }
    q.sz = 0;
    sum = 0;
    for(int i = C-Half; i < C; i++) {
        sum += cow[i].se;
        q.push(cow[i].se);
    }
    for(int i = C-Half; --i >= Half; ){
        if(sum + preSum[i] + cow[i].se <= F) return cow[i].fi;
        if(q.top() > cow[i].se) {
            sum -= q.top();
            q.pop();
            sum += cow[i].se;
            q.push(cow[i].se);
        }
    }
    return -1;
}

//#define LOCAL
int main()
{
#ifdef LOCAL
    freopen("in.txt","r",stdin);
#endif

    scanf("%d%d%d",&N,&C,&F);
    for(int i = 0; i < C; i++){
        scanf("%d%d",&cow[i].fi,&cow[i].se);
    }
    printf("%d
",sol());
    return 0;
}
原文地址:https://www.cnblogs.com/jerryRey/p/4889437.html