标签:数学


2 3 2 -1 0 1 4 2 -2 -1 1 2
0 0.5
题意:
给你n个点,排序后可以删除m个点,然后找一个点(可以不是这n个点),求所有点到这个点的距离的平方和
思路:暴力枚举左边删除几个点,右边删除几个点,然后求出所求取优
但是怎么求所求呢?假设那个点为t,那么就是(x1-t)^2+(x2-t)^2+.....(xn-t)^2
我这里取n为3时方便 就是x1*x1 +x2*x2 +x3*x3 -2(x1+x2+x3)*t+3*t*t,此时最优的答案 t 是(x1+x2+x3)/3 (注意题目是n个点删除m个,所以程序中应把3换成 n-m )
然后把t带入就可以了
详情看代码,不懂就看上面的式子
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define MID(x,y) ((x+y)>>1)
using namespace std;
#define INF 0x3f3f3f3f
#define N 50005
double a[N],sum[N],temp[N];
int n,m;
double fdd(int s,int e) //s是左边删除的点个数,e是右边删除的点个数
{
int i,j;
s=1+s; //算出左起点
e=n-e; //算出右终点
double t=(temp[e]-temp[s-1])/(n-m);
return sum[e]-sum[s-1]-2*(temp[e]-temp[s-1])*t+(n-m)*t*t; //不懂看上面的式子
}
int main()
{
int i,j,t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
sum[0]=temp[0]=0;
for(i=1;i<=n;i++)
{
scanf("%lf",&a[i]);
}
sort(a+1,a+n+1);
for(i=1;i<=n;i++)
{
sum[i]=sum[i-1]+a[i]*a[i];
temp[i]=temp[i-1]+a[i];
}
double ans=fdd(0,m);
if(n-m<=1)
{
printf("0.0000000000\n");
continue;
}
for(i=0;i<=m;i++)
ans=min(ans,fdd(i,m-i));
printf("%.10f\n",ans);
}
return 0;
}
标签:数学
原文地址:http://blog.csdn.net/u014737310/article/details/40402577