zoukankan      html  css  js  c++  java
  • 【2017泉州基地校集训】最优排名[贪心]

    My Solution

    我们定义“干掉”一个人的花费为他的空间减去他的分数再加一(易得)。

    由题可知,我们可以把除自己之外的选手分为“气球多于自己”和“气球少于自己”的两组。每次把自己的气球送给“气球多于自己”的中“花费最小的”,把他从这一组中去掉(干掉),再把一些选手从“气球少于自己”的一组移到“气球多于自己”的一组,更新自己当前的排名。

    以上过程相当于一次模拟,自己的气球数和排名都得到了更新,不断进行这样的模拟,直到自己的气球数不足以干掉“气球多于自己”的任何一名选手为止,取这一过程中排名的最小值即为最终的答案(事实证明这种贪心策略是正确的)。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    using namespace std;
    #define inf 0x3f3f3f3f
    
    typedef long long ll;
    
    ll read(){
        char ch;
        ll re=0;
        bool flag=0;
        while((ch=getchar())!='-'&&(ch<'0'||ch>'9'));
        ch=='-'?flag=1:re=ch-'0';
        while((ch=getchar())>='0'&&ch<='9')  re=re*10+ch-'0';
        return flag?-re:re;
    }
    
    struct node{
        ll w,c;
        node(ll w=0,ll c=0):
            w(w),c(c){}
    };
    
    const int maxn=300005;
    
    int n,ans=0,ens,cnt=0;
    ll w1;
    vector<node> a;
    node b[maxn],temp;
    
    //大根堆的排序与普通排序相反 
    inline bool cmp1(const node &n1,const node &n2){
        return n1.c>n2.c;
    } 
    
    inline bool cmp2(const node &n1,const node &n2){
        return n1.w>n2.w;
    }
    
    void init(){
        n=read()-1;  w1=read();
        ll w,tmp=read();
        for(int i=1;i<=n;i++){
            w=read();  tmp=read();
            //初始排名在小A之前 
            if(w>w1){
                a.push_back(node(w,tmp-w+1));
                ++ans;
            }
            else{
                b[++cnt]=node(w,tmp-w+1);
            }
        }
        ens=++ans;
    }
    
    void solve(){
        make_heap(a.begin(),a.end(),cmp1);
        sort(b+1,b+cnt+1,cmp2);
        //在b中的指针 
        int g=1;
        //ens==1时自然是最优解? 
        while(w1>0&&ens>1){
            //当前的气球不够 
            if(w1<a[0].c)  break;
            //模拟 
            w1-=a[0].c;
            //处理完了,把a[0]放到队尾,去掉队尾 
            pop_heap(a.begin(),a.end(),cmp1);  a.pop_back();
            ens--;
            while(g<=cnt&&b[g].w>w1){
                a.push_back(b[g]);
                //对新放入a的元素进行一次堆排(应该放到队首?) 
                push_heap(a.begin(),a.end(),cmp1);
                g++;
                ens++;
            }
            //更新答案 
            ans=min(ans,ens);
        }
        printf("%d
    ",ans);
    }
    
    int main(){
        //freopen("rank.in","r",stdin);
        //freopen("rank.out","w",stdout);
        
        init();
        solve();
        
        return 0;
    }
  • 相关阅读:
    数据分析的主要内容仍是结构化计算_数据分析师
    数据分析的主要内容仍是结构化计算_数据分析师
    在Excel工作表单元格中引用当前工作表名称
    在Excel工作表单元格中引用当前工作表名称
    茶叶店也可以用数据分析
    茶叶店也可以用数据分析
    业务实践,数据分析应从细节入手_数据分析师
    业务实践,数据分析应从细节入手_数据分析师
    2014新浪研发project师实习笔试(哈尔滨站)
    uva--10714+找规律
  • 原文地址:https://www.cnblogs.com/ZYBGMZL/p/7246457.html
Copyright © 2011-2022 走看看