题目链接: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