D. Boboniu Chats with Du(暴力枚举)

本文详细解析了一种针对快乐因子的优化算法,通过将快乐因子分为大于m和小于等于m两类,采用枚举策略选择最优组合,实现了在限制条件下的最大收益。算法巧妙地利用了闭嘴天数的特点,通过合理安排快乐因子的使用顺序,避免了不必要的闭嘴时间,从而达到整体效果的最优化。

我吐了

这D题真的很水,难度和A题差不多(真的不夸张,很多人只是没看题把)

你要是没做出来,真的很不应该

把快乐因子分成两种,一种是大于m的,选了后,肯定闭嘴d天把快乐因子分成两种,一种是大于m的,选了后,肯定闭嘴d天,m,,d

一种是小于等于m的,选了后,没事哦一种是小于等于m的,选了后,没事哦m,,~

那我们直接枚举选几个快乐因子大于m的不就行了吗?那我们直接枚举选几个快乐因子大于m的不就行了吗?m?

比如选x个快乐因子大于m的,那我肯定拿x个快乐因子最大的,反正都是闭嘴比如选x个快乐因子大于m的,那我肯定拿x个快乐因子最大的,反正都是闭嘴xm,x,

其中有一个快乐因子在第n天放,这样这次就不用闭嘴了,只需要消耗1天其中有一个快乐因子在第n天放,这样这次就不用闭嘴了,只需要消耗1天n,,1

所以此时消耗了(x−1)∗(d+1)+1所以此时消耗了(x-1)*(d+1)+1(x1)(d+1)+1

剩下的几天,都选快乐因子小于等于m的且最大的,反正不用闭嘴了嘛剩下的几天,都选快乐因子小于等于m的且最大的,反正不用闭嘴了嘛,m,

#include <bits/stdc++.h>
using namespace std;
#define int long long
int a[100009],b[100009],pre[100009];
int top1,top2,n,d,m;
bool com(int q,int w){
	return q>w;
}
signed main()
{
	cin >> n >> d >> m;
	for(int i=1;i<=n;i++)
	{
		int x; scanf("%lld",&x);
		if( x<=m )	a[++top1]=x;//不被禁言的 
		else	b[++top2]=x;//要被禁言的 
	}
	sort(a+1,a+1+top1,com);
	sort(b+1,b+1+top2,com);
	for(int i=1;i<=n;i++)	pre[i]=pre[i-1]+a[i];
	int sumn=0,ans=pre[n];
	//我这里强调一点,评论区也有朋友指出了
	//我们把其中一个大于m的放在n位置可以省掉这次的禁言时间
	//所以选x个大于m的最少花费(n-1)*(d+1)+1天,记作q
	//若最后一个不放在n,则最多可能禁言天数完全占满,最多花费n*d天,记作w
	//下面计算剩余可用的天数实际上是一个区间,[n-w,n-q]
	//若小于m的总天数不在这个区间范围,说明根本不能形成(填充)一个排列
	//在这个区间范围,我们肯定选可利用天数最多的,也就是yu=n-q
	for(int j=1;j<=top2;j++)//被禁言几次
	{
		sumn+=b[j];
		int yu=(j-1)*(d+1)+1;
		if( yu>n )	break;
		yu=n-yu;//现在最多还可以选yu个不大于m的
		ans=max(ans,sumn+pre[yu] );
	} 
	cout << ans;
} 
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值