Problem
可移动k个行星,使所有行星的转动惯量和最小,每个行星质量为1,中心为平均位置。
Solution
只有当剩下的n-k个位置连续时才有可能作为答案,不连续一定不是最优;剩下的k个一定是移动到这n-k个的平均位置时才有可能最优(用二次函数最小值位置可证);维护前缀和和前缀平方和,扫一遍计算答案即可
Code
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;
int t,n,k;
double a[50005],sum[50005],summ[50005],ans;
int main()
{
cin>>t;
while(t--)
{
ans=1e18;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%lf",&a[i]);
if(n==k)
{
cout<<0<<endl;
continue;
}
sort(a+1,a+1+n);
for(int i=1;i<=n;i++)
{
sum[i]=a[i]+sum[i-1];
summ[i]=a[i]*a[i]+summ[i-1];
}
for(int i=n-k;i<=n;i++)
{
double x=(sum[i]-sum[i-n+k])/(n-k);
ans=min(ans,summ[i]-summ[i-n+k]-2*(sum[i]-sum[i-n+k])*x+(n-k)*x*x);
}
printf("%.10lf\n",ans);
}
}