您的位置:首页 > 其它

HDU5073 ACM-ICPC亚洲区域赛鞍山赛区现场赛D题 Galaxy 贪心+数学推导

2014-10-27 19:57 483 查看


Galaxy

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)

Total Submission(s): 1396 Accepted Submission(s): 317

Special Judge

Problem Description

Good news for us: to release the financial pressure, the government started selling galaxies and we can buy them from now on! The first one who bought a galaxy was Tianming Yun and he gave it to Xin Cheng as a present.



To be fashionable, DRD also bought himself a galaxy. He named it Rho Galaxy. There are n stars in Rho Galaxy, and they have the same weight, namely one unit weight, and a negligible volume. They initially lie in a line rotating around their center of mass.

Everything runs well except one thing. DRD thinks that the galaxy rotates too slow. As we know, to increase the angular speed with the same angular momentum, we have to decrease the moment of inertia.

The moment of inertia I of a set of n stars can be calculated with the formula



where wi is the weight of star i, di is the distance form star i to the mass of center.

As DRD’s friend, ATM, who bought M78 Galaxy, wants to help him. ATM creates some black holes and white holes so that he can transport stars in a negligible time. After transportation, the n stars will also rotate around their new center of mass. Due to financial
pressure, ATM can only transport at most k stars. Since volumes of the stars are negligible, two or more stars can be transported to the same position.

Now, you are supposed to calculate the minimum moment of inertia after transportation.

Input

The first line contains an integer T (T ≤ 10), denoting the number of the test cases.

For each test case, the first line contains two integers, n(1 ≤ n ≤ 50000) and k(0 ≤ k ≤ n), as mentioned above. The next line contains n integers representing the positions of the stars. The absolute values of positions will be no more than 50000.

Output

For each test case, output one real number in one line representing the minimum moment of inertia. Your answer will be considered correct if and only if its absolute or relative error is less than 1e-9.

Sample Input

2
3 2
-1 0 1
4 2
-2 -1 1 2


Sample Output

0
0.5


这是最后鞍山赛区的题目,其实更像一个推公式的题目,意思就是给你n个数字,然后你最多可以去掉k个数字,求去掉后方差(不除n)最小,题目中给的是转移,其实转移到最后的平均值上就相当于是去掉,理解方式一样,我们现场赛时候的确队友yy了一个思路就是每次去除最大值和最小值中离平均数较远的数字,但是也是因为这个,现场赛WA了一发,后来,的确我感觉到这个思路很不可搞,就是双端数据,就是很小地方集中一堆数据,很大地方也一样,这样应该去除一部分,赛后的确在群里看到了这样的数据,就是:

5 3

1 2 3 100 100

最后,我就想到2个关于这道题的推论

1、最小方差一定要去掉k个数字

2、最小方差一定要保留一段从小到大连续数字

然后根据这个推论,我想到了枚举每一段连续n-k个数,然后计算方差,并得到最小的,具体实现可以直接线性扫,也就是对于a1,a2……at,可以得到

方差=∑(ai-ave)^2=∑ai^2-2*ave∑ai-t*ave^2=∑ai^2-2*(∑ai)^2/t+(∑ai)^2/t=∑ai^2-(∑ai)^2/t

有了这个公式以后直接线性扫一遍就可以过了,最后现场赛总算还能AC这个题目,也是比较开心的~~

但是赛后,赛题重现的确也有人说,就是直接看前n-k个和后n-k个中,输出小的那个也可以AC,这个只能说,数据真水,这个秒秒种提出一个反例,比如:

6 2

1 2 3 3 4 5

但是现场赛没人敢这么浪吧~~

具体正确思路代码如下:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
using namespace std;
const int MAXN=50005;
double a[MAXN];
int main()
{
//freopen("in.txt","r",stdin);
int t;
cin>>t;
while(t--)
{
int n,k;
cin>>n>>k;
for(int i=0;i<n;i++)
cin>>a[i];
if(n-k<=1)
{
cout<<"0"<<endl;
continue;
}
sort(a,a+n);
double sum=0,psum=0;
int tt=n-k;
for(int i=0;i<tt;i++)
{
sum+=a[i];
psum+=a[i]*a[i];
}
double minn=psum-sum*sum/tt;
for(int i=tt;i<n;i++)
{
sum+=a[i];
sum-=a[i-tt];
psum+=a[i]*a[i];
psum-=a[i-tt]*a[i-tt];
double item=psum-sum*sum/tt;
if(item<minn)
minn=item;
}
printf("%.12lf\n",minn);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐