$2016$长城信息杯中国大学生程序设计竞赛中南邀请赛$D$题
贪心。
我是这样贪的:开三个优先队列$q[0]$,$q[1]$,$q[2]$,$q[i]$存储对$3$取余之后为$i$的数。
首先看看还有没有$x\% 3 = 2$的$x$存在,如果有,那么这一次的$Arcane$ $Shot$就用在这个$x$上,更新答案与队列的情况。
如果$x\%3=2$的$x$不存在,那么看看$x\%3=1$的$x$是否存在,如果有,那么这一次的$Arcane$ $Shot$就用在这个$x$上,更新答案与队列的情况。
如果$x\%3=1$的$x$不存在,那么看看$x\%3=0$的$x$是否存在,如果有,那么这一次的$Arcane$ $Shot$就用在这个$x$上,更新答案与队列的情况。
具体看代码:
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<iostream> using namespace std; typedef long long LL; const double pi=acos(-1.0),eps=1e-8; const int maxn=100010; int n,m,f[maxn],mod=1e9+7; int main() { while(~scanf("%d%d",&n,&m)) { priority_queue<int>q[3]; memset(f,0,sizeof f); for(int i=1;i<=n;i++) { int x; scanf("%d",&x); q[x%3].push(x); f[0]=(f[0]+x/3)%mod; if(x%3!=0) f[0]=(f[0]+1)%mod; } bool flag=0; for(int i=1;i<=m;i++) { if(!q[2].empty()) { int h=q[2].top(); q[2].pop(); f[i]=f[i-1]-1; if(h-2>0) q[0].push(h-2); } else if(!q[1].empty()) { int h=q[1].top(); q[1].pop(); f[i]=f[i-1]-1; if(h-2>0) q[2].push(h-2); } else if(!q[0].empty()) { if(flag==0) f[i]=f[i-1], flag=1; else { int h=q[0].top(); q[0].pop(); f[i]=f[i-1]-1; if(h-4>0) q[2].push(h-4); flag=0; } } else f[i]=f[i-1]; } int ans=0; for(int i=0;i<=m;i++) ans=(ans+f[i])%mod; cout<<ans<<endl; } return 0; }