标签:数学
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