題目鏈接: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的。