题目链接
题目大意:把 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;
}