2014鞍山站 D - Galaxy(数论+贪心)

来源:互联网 发布:ubuntu git 安装 编辑:程序博客网 时间:2024/04/29 20:45

题目地址

题目大意:给出n,k(n<=50000,k<=n),及n个x轴位置,可从这n个点中拿走k个点,求剩余点与某个点的距离平方和最小

解题思路:首先判断n是否严格大于k,若大于,则本题相当于求(Xi-X均)^2之和最小,要求得最小值贪心舍掉连续k个点

令sum为Xi的和,m为留下的Xi的个数,则X均 = sum/m

(Xi-X均)^2 = Xi^2+m*X均^2-2*Xi*X均

m个数的(Xi-X均)^2 为 ( X1^2+X2^2+......+Xm^2)+m*(sum/m)*(sum/m)-2* sum*(sum/m)→( X1^2+X2^2+......+Xm^2)+* sum*(sum/m)

将给出点按照位置从小到大排序,枚举留下的点即可


#include <bits/stdc++.h>using namespace std;const int maxn = 5e4+100;double a[maxn];int main(){    int t,n,k;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&k);        for(int i = 0; i < n; i++)            scanf("%lf",&a[i]);        int m = n-k;        if(m <= 0)        {            puts("0");            continue;        }        sort(a,a+n);        double sum1 = 0;        double sum2 = 0;        for(int i = 0; i < m; i++)        {            sum1 += a[i];            sum2 += a[i]*a[i];        }        double minn = sum2-sum1*sum1/(double)m;        for(int i = m; i < n; i++)        {            sum1 -= a[i-m];            sum2 -= a[i-m]*a[i-m];            sum1 += a[i];            sum2 += a[i]*a[i];            minn = min(minn,sum2-sum1*sum1/m);        }        printf("%.10lf\n",minn);    }    return 0;}


0 0
原创粉丝点击