F. Equalize the Array (map、思维)

题目

思路:
看一个例子
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;
	}
}

猜你喜欢

转载自blog.csdn.net/asbbv/article/details/113839796