村ごとに計算する。1番近い村が選ばれる確率、2番目に近い村が選ばれる確率、... を計算する。
これを間違わずに実装できる気がしないけれど、本番での正答率はそれなり。
ツラい。
double e_dist(int ax, int ay, int bx, int by) { double x = (ax - bx); double y = (ay - by); return sqrt(x * x + y * y); } class KingdomXCitiesandVillages { public: double determineLength(vector <int> cX, vector <int> cY, vector <int> vX, vector <int> vY) { const int C = cX.size(); const int V = vX.size(); const int F = 50 + 5; double f[F]; f[0] = 1; for (int i = 1; i < F; ++i) { f[i] = f[i - 1] * i; } double ret = 0; for (int i = 0; i < V; ++i) { vector<double> ds; double mnC = 1e128; for (int j = 0; j < C; ++j) { mnC = min(mnC, e_dist(vX[i], vY[i], cX[j], cY[j])); } for (int j = 0; j < V; ++j) { if (i != j) ds.push_back(e_dist(vX[i], vY[i], vX[j], vY[j])); } sort(ds.begin(), ds.end()); for (int j = 0; j < V - 1; ++j) { for (int k = 1; k <= (V - 1 - j); ++k) { int l = (V - 1) - (j + 1); double a = f[l] / f[l - (k - 1)]; double b = f[k - 1]; double c = a / b; // nCk double prob = c * f[k] * f[V - 1 - k] / f[V]; double dist = min(mnC, ds[j]); ret += prob * dist; } } ret += mnC * f[V - 1] / f[V]; } return ret; }