# 2428: [HAOI2006]均分数据

341人阅读 评论(0)

## 2428: [HAOI2006]均分数据

Time Limit: 5 Sec  Memory Limit: 128 MB
Submit: 1660  Solved: 500
[Submit][Status][Discuss]

## Description

,其中σ为均方差，是各组数据和的平均值，xi为第i组数据的数值和。

（同一行的整数间用空格分开）

6 3
1 2 3 4 5 6

0.00

## Source

[Submit][Status][Discuss]

RP算法--模拟退火

#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<bitset>
#include<algorithm>
#include<cstring>
#include<map>
#include<stack>
#include<set>
#include<cmath>
#include<ctime>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;

typedef double DB;

int n,m,a[22],belong[22];
DB Ave,ans = 1E18,sum[10];

DB Pow(DB x) {return x*x;}
void Fire()
{
for (int i = 1; i <= m; i++)
sum[i] = 0;
for (int i = 1; i <= n; i++) {
int Num = rand()%m + 1;
sum[Num] += a[i];
belong[i] = Num;
}
DB Now = 0;
for (int i = 1; i <= m; i++)
Now += Pow(sum[i] - Ave);

DB T = 10000;
while (T > 0.1) {
T *= 0.9;
int x = rand()%n + 1;
DB tmp = Now,k = a[x];
int A = belong[x],B;
if (T > 500) {
DB Min = 1E18;
for (int i = 1; i <= m; i++)
if (sum[i] < Min)
Min = sum[i],B = i;
}
else B = rand()%m + 1;
if (A == B) continue;
Now -= Pow(sum[A] - Ave);
Now -= Pow(sum[B] - Ave);
sum[A] -= k;
sum[B] += k;
Now += Pow(sum[A] - Ave);
Now += Pow(sum[B] - Ave);
if (Now > tmp) {
int pass = rand()%10000;
if (pass > T) {
sum[A] += k;
sum[B] -= k;
Now = tmp;
continue;
}
}
belong[x] = B;
}
ans = min(ans,Now);
}

int main()
{
#ifdef DMC
freopen("DMC.txt","r",stdin);
#endif

//srand(19990720);
cin >> n >> m;
for (int i = 1; i <= n; i++) {
scanf("%d",&a[i]);
Ave += (DB)(a[i]);
}
Ave /= (DB)(m);
for (int i = 1; i <= 10000; i++)
Fire();
printf("%.2lf",sqrt(ans/(DB)(m)));
return 0;
}


个人资料
等级：
访问量： 21万+
积分： 9091
排名： 2518
文章分类
最新评论