hdu 5073 有坑+方差贪心

来源:互联网 发布:java 下载https图片 编辑:程序博客网 时间:2024/06/11 01:34

http://acm.hdu.edu.cn/showproblem.php?pid=5073

就是给你 n 个数,代表n个星球的位置,每一个星球的重量都为 1
开始的时候每一个星球都绕着质心转动,那么质心的位置就是所有的星球的位置之和 / 星球的个数
现在让你移动 k 个星球到任意位置(多个星球可以在同一个位置并且所有的星球在同一直线上)
移动之后那么它们质心的位置就可能发生变化,求 I = sum(di^2) (di表示第i个星球到达质心的距离)最小


根据方差的性质(越密越小)得知贪心策略就是,n-k序列一定连续,那么随即求连续n-k序列里面方差最小的那个

设连续长度为k

avg = sum/k;

有 求和(pi - avg)^2 = (求和pi^2)   -  sum^2/k;

然后贪心模拟一遍即可

输入序列式无序的,样例坑到死,不sort或者sum^2/k精度问题WA到死


#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <string>#include <queue>#include <stack>#include <iostream>#include <algorithm>using namespace std;#define RD(x) scanf("%I64d",&x)#define RD2(x,y) scanf("%d%d",&x,&y)#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)#define clr0(x) memset(x,0,sizeof(x))typedef long long LL;const int maxn = 5e4+5;const double INF = 1e20;int n,k;LL p[maxn],sum[maxn],sq[maxn];int main() {    int _;RD(_);while(_--){        RD2(n,k);        p[0] = sum[0] = sq[0] = 0;        for(int i = 1;i <= n;++i)            RD(p[i]);        double ans = INF;        k = n - k;        if(k == 0 || k == 1){            puts("0");            continue;        }        sort(p+1,p+n+1);        for(int i = 1;i <= n;++i)            sum[i] = p[i] + sum[i-1],sq[i] = p[i]*p[i] + sq[i-1];        for(int i = k;i <= n;++i)            ans = min(ans,(double)(sq[i] - sq[i - k])*(double)k - (double)(sum[i] - sum[i-k])*(double)(sum[i] - sum[i-k]));        printf("%.10lf\n",ans/(double)k);    }    return 0;}


0 0
原创粉丝点击