Codeforces Round #664 (Div. 1) A. Boboniu Chats with Du 题解

515 阅读1分钟

题目链接

思路

取笑可以分为两种,一种不会被禁言(小于等于mm),称之为aa,一种会被禁言(大于mm),称之为bb。枚举用了多少bb即可。
加入了两个优化:如果选的bb太少,也就是说用选的这些bb带来的禁言天数并不能把其他不想选的bb全部覆盖掉,就跳过。如果选的bb太多,在有限的天数内不能把这些bb都塞进去,就退出。
看大佬代码发现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;
}