HDU

来源:互联网 发布:淘宝客服链接 编辑:程序博客网 时间:2024/06/15 22:02

题目链接

题意:

一共有N个星球,其星球围绕着其中心旋转,现在你可以去掉最多K个星球,使得其最后的:ni=1d2i最小 其中di表示第i个点到中心的距离。当然随着点的去掉,中心一定是不同的。

思路:

1.首先设此时的中心的位置为x,那么上述式子为: ni=1(aix)2 展开之后得到 nx22xni=1ai+ni=1a2i 。现在我们要求这个的最小值,发现这是一个一元二次函数,开口朝上,最小值就在对称轴处,为 ni=1ain 不同的只是,随着去掉一些点n的个数会变.

2.根据上面的式子我们发现中心x即为n个数的平均值处.进而发现 ni=1(aix)2其实是一个方差.
根据方差存在的性质,点数越少,越密集,方差值越小,越稳定.从而发现其实这个题一定是要去掉k个点才能最优的,并且去掉的点要放在中心位置使得对答案没有贡献.

3.为了使点数更密集,那么我们留下的n-k个点一定要是连续的了,我们就对点排序,然后维护两个前缀和求个最优即可.

这个过程有很多坑点,比如当n == k时

#include<bits/stdc++.h>using namespace std;const int maxn = 5e5+5;typedef long long ll;int n,k;ll pos[maxn],sum1[maxn],sum2[maxn];const ll inf = 1e18;int main(){    int _;    cin>>_;    while(_--)    {        scanf("%d %d",&n,&k);        for(int i = 1;i <= n;++i)         scanf("%lld",&pos[i]);        sort(pos+1,pos+1+n);//排序         sum1[0] = sum2[0] = 0;        for(int i = 1;i <= n;++i)        {            sum1[i] = sum1[i-1]+pos[i];            sum2[i] = sum2[i-1]+pos[i]*pos[i];        }        double ans = inf;        for(int i = n - k;i <= n;++i)        {            ll s1 = sum1[i] - sum1[i-(n-k)];            ll s2 = sum2[i] - sum2[i-(n-k)];            double mid = s1*1.0/(n-k);            double I = (n-k)*mid*mid - 2*mid*s1 + s2;            ans = min(I,ans);         }        if(n == k) ans = 0;//坑点         printf("%.10f\n",ans);    }    return 0;}

方差性质:
1.方差刻画了随机变量的取值对于其数学期望的离散程度。(标准差、方差越大,离散程度越大)
2.若X的取值比较集中,则方差D(X)较小,若X的取值比较分散,则方差D(X)较大。
3.点数越少,越密集,方差值越小,越稳定
各种分布