P2503 [HAOI2006]均分数据
随机算法。真香!
这道题一看上去好像很可怕的样子,根本想不出什么算法。
全部情况都枚举一遍显然不可能,铁铁的T掉。
没办法全都枚举,那就随机乱搞!
我们可以使用std::ramdon_shuffle
这个函数,每次打乱a数组,然后每一次添加数据的时候贪心地往当前组内和最小的加就是了。
一次极小概率碰到正解,但这种随机算法你能跑200000次!必定得到最优答案。
代码:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
const int maxn = 21, maxm = 7;
const double INF = 999999999;
int a[maxn], n, m;
int sum[maxm];
double ans = INF;
void solve()
{
memset(sum, 0, sizeof sum);
std::random_shuffle(a + 1, a + n + 1);
for(int i = 1; i <= n; i++)
{
int minidx = -1, minv = INF;
for(int j = 1; j <= m; j++)
{
if(sum[j] < minv) minv = sum[j], minidx = j;
}
sum[minidx] += a[i];
}
double res = 0;
double avg = 0;
for(int i = 1; i <= m; i++) avg += sum[i];
avg /= m;
for(int i = 1; i <= m; i++) res += (sum[i] - avg) * (sum[i] - avg);
res /= m;
res = sqrt(res);
ans = std::min(ans, res);
}
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
for(int i = 1; i <= 200000; i++) solve();
printf("%.2lf\n", ans);
return 0;
}