洛谷P2503 [HAOI2006] 均分數據 題解 模擬退火

題目鏈接:https://www.luogu.com.cn/problem/P2503

模擬退火 + 貪心。

#include <bits/stdc++.h>
using namespace std;
int n, m, a[22], s[22], cnt[22];
double avga, ans = 1e9;

double cal() {
    memset(s, 0, sizeof(int)*m);
    memset(cnt, 0, sizeof(int)*m);
    for (int i = 0; i < n; i++) {
        int x = 0;
        for (int j = 1; j < m; j++)
            if (s[j] < s[x])
                x = j;
        s[x] += a[i];
        cnt[x]++;
    }
    double sum = 0;
    for (int i = 0; i < m; i++) {
        double dx = (double) s[i] - avga;
        sum += dx * dx;
    }
    sum = sqrt(sum / m);
    ans = min(ans, sum);
    return sum;
}

void sa() {
    random_shuffle(a, a+n);
    for (double t = 1e4; t >= 1e-4; t *= 0.993) {
        double cur = cal();
        int p = rand() % n, q = rand() % n;
        if (p == q) continue;
        swap(a[p], a[q]);
        double tmp = cal();
        double dt = tmp - cur;
        if (exp(-dt / t) < (double) rand() / RAND_MAX) {
            ;
        }
        else
            swap(a[p], a[q]);
    }
}

int main() {
    srand(time(NULL));
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i++) scanf("%d", a+i), avga += a[i];
    avga /= m;
    for (int i = 0; i < 500; i++)
        sa();
    printf("%.2lf\n", ans);
    return 0;
}

三分天註定,七分靠人品。上面代碼多提交幾次,總還是能AC的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章