Official

J - ポイントとコストと / Points to Cost Editorial by tatyam


\(\displaystyle\sum_{i=1}^N (C - Y_i)^2\) は定数なので、\(\displaystyle\sum_{i=1}^N (p - X_i)^2\) の最小化を考えます。

\((p - X_i)^2\)\(p\)\(2\) 次式です。\(2\) 次式と \(2\) 次式の和は \(2\) 次式なので、\(\displaystyle\sum_{i=1}^N (p - X_i)^2\) は下に凸であり、三分探索で高速に最小値を求められます。

また、\(\displaystyle\sum_{i=1}^N (p - X_i)^2\)\(p\) で微分すると \(\displaystyle\sum_{i=1}^N -2(p - X_i)\) です。
\(\displaystyle\sum_{i=1}^N -2(p - X_i) = 0\) を解くと、\(p = \text{average}(X_i)\) であるので、\(p = \text{average}(X_i)\) のときのコストが答えになります。

回答例 (C++)

#include <iostream>
#include <vector>
#include <numeric>
using namespace std;

int main(){
    int N;
    double C;
    cin >> N >> C;
    vector<int> X(N), Y(N);
    for(int i = 0; i < N; i++) cin >> X[i] >> Y[i];
    const double p = reduce(X.begin(), X.end(), 0LL) / double(N);
    cout.precision(10);
    cout << transform_reduce(X.begin(), X.end(), 0.0, plus<>{}, [p](int x){ return (x - p) * (x - p); })
          + transform_reduce(Y.begin(), Y.end(), 0.0, plus<>{}, [C](int y){ return (y - C) * (y - C); }) << endl;
}

回答例 (Python)

N, C = map(int, input().split())
X = [0] * N
Y = [0] * N
for i in range(N):
    X[i], Y[i] = map(int, input().split())
p = sum(X) / N
print(sum((x - p) * (x - p) for x in X) + sum((y - C) * (y - C) for y in Y))

posted:
last update: