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;
    }
  • 相关阅读:
    UGUI组件之Slider组件简单笔记
    UGUI事件之Drag拖拽事件
    C#的数据类型之最常用的几种类型
    UGUI组件之Text文本组件简单笔记
    UGUI组件之Toggle 组件简单笔记
    Print 与Debug.Log的区别
    Unity脚本用VS打开出现 "以下文件中的行尾不一致,要将行尾标准化吗?"
    UGUI组件之Image 组件简单笔记
    UGUI事件之Pointer指针事件
    定制自己的Unity脚本模板
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4889437.html
Copyright © 2011-2022 走看看