题目链接:HDU 5073 Galaxy
题面:


2 3 2 -1 0 1 4 2 -2 -1 1 2
0 0.5
解题:
重心的位置时所有位置的平均数,而能移动的点最后肯定都落在重心上。故只需找出哪些是保留的点,而保留的点应该是连续的,这样才能保证力矩之和最小。直接暴力是n^2,显然会超时。因为要求的是,∑从1到n(d^2),而(di-dave)^2可以拆分成di^2-2*di*dave+dave^2可以先预处理di和di^2的累积和,最后算的时候直接取就行了。因为初值取太小了,导致wa多次。貌似是需要,排下序的。
总结:
1.不要认为题目给定的都是有序的。
2.求最值,初值应设为第一项或末项的值。
代码:
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
using namespace std;
int main()
{
int t,n,k;
long long int p[50000+10];
long long int d[50000+10];
long long int ds[50000+10];
double center;
double minn=0,temp;
cin>>t;
while(t--)
{
minn=9999999999999999;
cin>>n>>k;
for(int i=1;i<=n;i++)
cin>>p[i];
sort(p+1,p+n+1);
if(n==k||n-k==1)
{
printf("0\n");
continue;
}
d[0]=0;
ds[0]=0;
for(int i=1;i<=n;i++)
{
d[i]=d[i-1]+p[i];
ds[i]=ds[i-1]+p[i]*p[i];
}
for(int i=0;i<=k;i++)
{
center=(d[i+n-k]-d[i])*1.0/(n-k);
temp=(ds[i+n-k]-ds[i])-2*center*(d[i+n-k]-d[i])+(n-k)*center*center;
if(temp<minn)
minn=temp;
}
printf("%.9f\n",minn);
}
return 0;
}版权声明:本文为博主原创文章,未经博主允许不得转载。
原文:http://blog.csdn.net/david_jett/article/details/46777169