码迷,mamicode.com
首页 > 其他好文 > 详细

ACM/ICPM2014鞍山现场赛D Galaxy (HDU 5073)

时间:2015-12-17 19:18:39      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:

题目链接: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\n");
            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\n",ans);
    }
    return 0;
}
/***
100
3 2
-1 0 1
4 2
-2 -1 1 2
****/


ACM/ICPM2014鞍山现场赛D Galaxy (HDU 5073)

标签:

原文地址:http://www.cnblogs.com/yxwkf/p/5054918.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!