【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\n",ans);
}

int main(){
    //freopen("rank.in","r",stdin);
    //freopen("rank.out","w",stdout);
    
    init();
    solve();
    
    return 0;
}

 

posted @ 2017-07-27 18:23  ZYBGMZL  阅读(240)  评论(0编辑  收藏  举报