思路
取笑可以分为两种,一种不会被禁言(小于等于),称之为,一种会被禁言(大于),称之为。枚举用了多少即可。
加入了两个优化:如果选的太少,也就是说用选的这些带来的禁言天数并不能把其他不想选的全部覆盖掉,就跳过。如果选的太多,在有限的天数内不能把这些都塞进去,就退出。
看大佬代码发现sort从大到小排序可以写成sort(a+1,a+n+1,greater<int>());
代码
#include<bits/stdc++.h>
#define rep(i,st,ed) for(ll i=st;i<=ed;++i)
using namespace std;
typedef long long ll;
const int N=1E5+10;
ll n,d,m,cnta,cntb,ans;
ll a[N],b[N];
int main()
{
scanf("%lld%lld%lld",&n,&d,&m);
rep(i,1,n)
{
ll tmp;
scanf("%lld",&tmp);
if(tmp>m)
b[++cntb]=tmp;
else
a[++cnta]=tmp;
}
sort(a+1,a+cnta+1,greater<ll>());
sort(b+1,b+cntb+1,greater<ll>());
rep(i,2,cnta)
a[i]+=a[i-1];
rep(i,2,cntb)
b[i]+=b[i-1];
rep(i,0,cntb)
{
if(i*d<cntb-i)
continue;
if((i-1ll)*(d+1ll)+1ll>n)
break;
ll pans=b[i];
ll p=max((i-1)*(d+1)+1,cntb);
pans+=a[n-p];
ans=max(ans,pans);
}
cout<<ans<<endl;
}