题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5073
题意:给定一条线上的点,然后能够去掉当中的m个,使剩下的到重心的距离最小,
因为重心等于距离的平均值。因此也就是求方差最小。
分析:
由于要去掉m个所以一定剩下n-m个,我们枚举这一串点的起始位置从1開始 一直枚举到m,
然后由平方和的公式展开。预处理一下前几项平方和。以及前几项的和就可以,复杂度为O(N);
代码例如以下:
#include <iostream> #include <cstring> #include <algorithm> #include <cstdio> using namespace std; const int maxn = 50010; long long a[maxn]; int main() { int n,m,t; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%I64d",&a[i]); if(n==m){ printf("0 "); continue; } sort(a+1,a+n+1); long long sum1=0,sum2=0; for(int i=1;i<=n-m;i++){ sum1+=a[i]; sum2+=a[i]*a[i]; } double mess = sum1*1.0/(n-m); double ans = sum2 + (n-m)*mess*mess - 2*sum1*mess; for(int i=1;i<=m;i++){ sum1 = sum1-a[i]+a[n-m+i]; sum2 = sum2 - a[i]*a[i]+a[n-m+i]*a[n-m+i]; mess = sum1*1.0/(n-m); ans = min(ans,sum2 + (n-m)*mess*mess - 2*sum1*mess); } printf("%.10lf ",ans); } return 0; } /*** 100 3 2 -1 0 1 4 2 -2 -1 1 2 ****/