@wsndy-xx
2018-05-10T02:35:58.000000Z
字数 1393
阅读 1192
题解给出 个数, 分成 组,使得均方差最小
Ans 即为均方差模拟退火
退火时接受非最优解的条件
exp((NowAns - BefAns) / Now_tmep) * MAX_RAND < rand()
#include <bits/stdc++.h>const int N = 30;const double Delta = 0.99;const double eps = 1e-10;#define DB doubleint n, m, A[N], Bel[N];DB Aver, Answer, Sum[N];#define gc getchar()inline int read() {int x = 0; char c = gc;while(c < '0' || c > '9') c = gc;while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;return x;}inline int Get_short() {int Min = 1e9, ret;for(int i = 1; i <= m; ++ i)if(Sum[i] <= Min) Min = Sum[i], ret = i;return ret;}DB Work() {DB NowAns = 0;for(int i = 1; i <= n; ++ i) Sum[i] = 0;for(int i = 1; i <= n; ++ i) Bel[i] = rand() % m + 1, Sum[Bel[i]] += A[i];for(int i = 1; i <= m; ++ i) NowAns += (Sum[i] - Aver) * (Sum[i] - Aver);DB Now_temp = 10000;while(Now_temp >= eps) {int shor = std:: min_element(Sum + 1, Sum + m + 1) - Sum, x = rand() % n + 1;DB BefAns = NowAns;NowAns -= (Sum[shor] - Aver) * (Sum[shor] - Aver) + (Sum[Bel[x]] - Aver) * (Sum[Bel[x]] - Aver);Sum[shor] += A[x];Sum[Bel[x]] -= A[x];NowAns += (Sum[shor] - Aver) * (Sum[shor] - Aver) + (Sum[Bel[x]] - Aver) * (Sum[Bel[x]] - Aver);if(NowAns < BefAns || (exp((NowAns - BefAns) / Now_temp) * RAND_MAX < rand())) Bel[x] = shor;else Sum[shor] -= A[x], Sum[Bel[x]] += A[x], NowAns = BefAns;Now_temp *= Delta;}return NowAns;}int main() {srand(20001206); //meizibaoyoun = read(), m = read();for(int i = 1; i <= n; i ++) A[i] = read(), Aver += A[i];Aver /= m;int Ty = 1000;Answer = 1e18;for(; Ty; Ty --) Answer = std:: min(Answer, Work());printf("%.2lf", sqrt(Answer / m));return 0;}