题目链接:HDU 5073 Galaxy
题意:在一维的坐标系里,给出N个点坐标,转动K个点,使转动后这个星系的的惯性最小(根据题意惯性最小也就是 求所有星星到星系中心的距离最小,这个可以理解成方差最小)。求最小的惯性。
思路:
先对序列排序,再求出算N-K个点惯性的递推式。
以三个为例:
预处理是 平均数和各项的平方和,
注意:n==k的特判
AC代码:
#include <stdio.h>
#include <algorithm>
using namespace std;
double pf[50010],sum[50010];
double a[50010];
int main()
{
int t;
int n,k,i;
double ave,minans,tempfc;
scanf("%d",&t);
while(t--)
{
memset(pf,0,sizeof pf);
memset(sum,0,sizeof sum);
scanf("%d %d",&n,&k);
for(i=0;i<n;i++)
scanf("%lf",&a[i]);
if(n==k)
{
printf("%lf\n",0);
continue;
}
sort(a,a+n);
pf[0]=a[0]*a[0],sum[0]=a[0];
for(i=1;i<n;i++)
{
pf[i]=pf[i-1]+a[i]*a[i];
sum[i]=+sum[i-1]+a[i];
}
//以上预处理
ave=sum[n-k-1]*1.0/(n-k);
minans=pf[n-k-1]-2*ave*sum[n-k-1]+(n-k)*ave*ave;
for(i=n-k;i<n;i++)
{
ave=(sum[i]-sum[i-(n-k)])/(n-k);
tempfc=(pf[i]-pf[i-(n-k)])-2*ave*(sum[i]-sum[i-(n-k)])+(n-k)*ave*ave;
minans=min(minans,tempfc);
}
printf("%lf\n",minans);
}
return 0;
}
/*
10
3 2
-1 0 1
4 2
-2 -1 1 2
3 3
-1 0 1
*/