2017泉州基地校集训最优排名[贪心]
Posted ZYBGMZL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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; }
以上是关于2017泉州基地校集训最优排名[贪心]的主要内容,如果未能解决你的问题,请参考以下文章