2428: [HAOI2006]均分数据

题目链接

题目大意:把 n 个正整数分成 m 组,最小化各组的均方差

题解:模拟退火2333

我的收获:2333

#include 
#include 
#include 

using namespace std;
typedef double lf;
const int N = 25;

int n, m;
lf mid, ans;
int a[N], p[N];

inline lf sqr(lf x) {
    return x * x;
}

inline lf work() {
    int cnt = 1, sum = 0, i;
    lf tmp = 0, t1, t2;
    for (i = 1; i <= n && cnt < m; ++i)
        if (sum + a[p[i]] >= mid) {
            t1 = sqr(sum - mid), t2 = sqr(sum + a[p[i]] - mid);
            if (t1 < t2) tmp += t1, sum = a[p[i]];
            else tmp += t2, sum = 0;
            ++cnt;
        } else sum += a[p[i]];
    while (i <= n) sum += a[p[i++]];
    tmp += sqr(sum - mid);
    return tmp;
}

int main() {
    int i;
    scanf("%d%d", &n, &m);
    for (i = 1; i <= n; ++i) {
        p[i] = i;
        scanf("%d", a + i);
        mid += a[i];
    }
    mid /= m, ans = 1e60;
    for (i = 1; i <= 500000; ++i) {
        random_shuffle(p + 1, p + n + 1);
        ans = min(ans, work());
    }
    printf("%.2lf\n", sqrt(ans / m));
    return 0;
}

你可能感兴趣的:(2251-2500)