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