hdoj 5073 Galaxy【方差】

Galaxy

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 2911    Accepted Submission(s): 699
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 w i is the weight of star i, d i 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个行星质心为x,它们各自球心坐标为xi。那么(x1 - x)的平方 + (x2 - x)的平方 + (x3 - x)的平方 + ... + (xN - x)的平方) 就是这N个行星组成星系集合的转动惯量。

题意:给你N个球心在一条直线的行星,要求你最多可以移动k个行星(可以移到任意的位置,不同行星可以在同一个位置),问移动之后最小的转动惯量。



首先我们要明确:移动k个行星 决不会比 移动k-1个行星 所得到的转动惯量大,这样就是说,我们追求最优解要去移动k个行星。


推导:由题中所给的公式,对转动惯量J = (x1 - x) * (x1 - x) + ... + (xN - x) * ( xN - x) = x1 * x1 + x2 * x2 + ... + xN * xN + N * x * x - 2 *  x * N * x。

化简得 :J = x1 * x1 + x2 * x2 + ... + xN * xN  - N * x * x。

其实如果数学好的话就可以看出来J / N就是方差,然后方差 = 平方均值 - 均值的平方,可推出 J = 平方总和 - 均值平方乘以N 。可惜我忘了。。。


思路:先求出前N-k数的和以及平方和,然后每次去掉最前一位、后移一位构成新序列来求方差 并在这个过程中 更新最优值。

AC代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 50000+10
using namespace std;
double a[MAXN];
double sum, qsum;//记录区间和 和 区间平方和
int main()
{
    int t, N, k;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d%d", &N, &k);
        for(int i = 1; i <= N; i++)
            scanf("%lf", &a[i]);
        if(N <= k)//N等于k的情况下,除数为0
        {
            printf("0\n");
            continue;
        }
        sort(a+1, a+N+1);
        sum = qsum = 0;
        int len = N - k;
        for(int i = 1; i <= len; i++)
        {
            sum += a[i];
            qsum += a[i] * a[i];
        }
        double ans = qsum - sum * sum / len;
        for(int i = len+1; i <= N; i++)//枚举区间
        {
            sum -= a[i-len];
            sum += a[i];
            qsum -= a[i-len] * a[i-len];
            qsum += a[i] * a[i];
            ans = min(ans, qsum - sum * sum / len);
        }
        printf("%.10lf\n", ans);
    }
    return 0;
}






 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值