F. Equalize the Array (map、思维)

本文介绍了一种算法,通过实例演示如何在给定数值分布中删除最少元素,使剩余数量尽可能相同。通过逐步调整目标数量,展示了如何计算每一步的最优操作并更新结果。核心代码展示了如何使用C++实现这一过程,最终目标是找到在不同数量级下删除最少数量的解决方案。
摘要由CSDN通过智能技术生成

题目

思路:
看一个例子
x:y 表示 拥有x个相同的数有y个(2:3 1 1 2 2 3 3)

现在有 4:5 3:3 1:8 即 有5个数量为4的数 3个数量为3的数 8个数量为1的数

现在我们要求使得剩下的数的数量都相同的最少删去数的个数,即让剩下数的个数最大

我们假设要让最后所有的数都剩下数量为4,那么把1和3的所有数删掉即可,剩下数的个数4*5=20.

继续这个过程如要让剩下的数数量都为3,那么我们需将那5个数量为4的数各自删掉一个数,再加上所有数量为3的数,即为20-(4-3)*5+3 * 3=24,此时有3+5个数量为3的数

再继续,让剩下的数的个数都为1,需将8个数量为3的数都相减2再加上8个数量为1的数 24-(3-1)*8+1 *8=16.
最终答案取20 24 16 所有情况的最大值24

Code:

#include<iostream>
#include<map>
using namespace std;
typedef long long ll;
const int Max = 1e6 + 5;
int Mod = 1e9 + 7;
ll lst[Max];

int main()
{
	int t;cin >> t;
	while (t--)
	{
		map<ll, ll,greater<ll>> ma1, ma2;
		int n;cin >> n;
		for (int i = 1;i <= n;i++) { cin >> lst[i];ma1[lst[i]]++; }
		for (auto i = ma1.begin();i != ma1.end();i++)ma2[i->second]++;
		ll sum = ma2.begin()->first * ma2.begin()->second;
		ll ma = sum;auto j = ma2.begin();
		for (auto i = ++ma2.begin();i != ma2.end();i++)
		{
			sum += i->first * i->second;
			sum -= (j->first - i->first) * j->second;
			i->second += j->second;
			ma = max(ma, sum);
			j = i;
		}
		cout << n - ma << endl;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_Rikka_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值