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;
}
posted @ 2018-10-21 11:09  Garen-Wang  阅读(133)  评论(0编辑  收藏  举报