zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    HDU Problem 1811 Rank of Tetris【拓扑排序+并查集】
    POJ Problem 2367 Genealogical tree【拓扑排序】
    HDU Problem 2647 Reward【拓扑排序】
    HDU Problem 1285 确定比赛名次【拓扑排序】
    HDU Problem HDU Today 【最短路】
    HDU Problem 3665 Seaside【最短路】
    HDU Problem 一个人的旅行 【最短路dijkstra】
    HDU Problem 1596 find the safest road【最短路dijkstra】
    Beyond Compare文本合并进行内容替换要注意什么
    用这些工具都可以比较代码的差异
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4889437.html
Copyright © 2011-2022 走看看