E 分组
题目大意:
有n个人,每个人有一个分类,现在请你将他们分成m个组,顺利安排后最多人数最少。
思路:
首先考虑-1的情况。 一定是不同的声部数大于m,显然怎么分都不可以,输出-1.
对于这种最大值最小,考虑用二分来解。
每次二分出一个mid对于每一个组最多2可以容纳多少个人,如果最后分组数小于m,mid缩小,反之亦然。
#include <cstdio>
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
int n, m, a[N], cnt[N], f[N], tot;
bool check(int x)
{
int ans = 0;
for(int i = 1; i <= tot; i++) ans += (!(f[i] % x) ? f[i] / x : f[i] / x + 1);
return ans <= m;
}
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]), cnt[a[i]]++;
for(int i = 1; i <= n; i++)
if(cnt[i]) f[++tot] = cnt[i];
if(tot > m) {printf("-1\n"); return 0;}
int l = 1, r = n + 1;
while(l < r)
{
int mid = (l + r) >> 1;
if(check(mid)) r = mid;
else l = mid + 1;
}
printf("%d\n", l);
return 0;
}