Scapegoat Gym - 101775B

http://codeforces.com/gym/101775/problem/B

贪心 先分出n个人 对于剩下的m个人怎么分 就看分给哪个任务使方差减少最多 优先队列维护一下

具体证明不会 只是觉的这样一个人一个人的分 每次都使各个值尽量接近平均值是对的

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

struct node
{
    bool friend operator < (node n1,node n2)
    {
        return n1.val*n1.val*n2.cnt*(n2.cnt+1)<n2.val*n2.val*n1.cnt*(n1.cnt+1);
    }
    ll val;
    ll cnt;
};

priority_queue <node> que;
int n,m;

int main()
{
    double ans,ave,t,gou;
    node tmp;
    ll sum;
    int tt,cas,i;
    scanf("%d",&tt);
    for(cas=1;cas<=tt;cas++)
    {
        scanf("%d%d",&n,&m);
        while(!que.empty()) que.pop();
        sum=0;
        for(i=1;i<=n;i++)
        {
            scanf("%lld",&tmp.val);
            tmp.cnt=1;
            que.push(tmp);
            sum+=tmp.val;
        }
        ave=(double)(sum)/(double)(m);
        i=m-n;
        while(i--)
        {
            tmp=que.top();
            que.pop();
            tmp.cnt++;
            que.push(tmp);
        }
        ans=0.0;
        while(!que.empty())
        {
            tmp=que.top();
            que.pop();
            //printf("*%lld %lld*\n",tmp.val,tmp.cnt);
            t=(double)(tmp.val)/(double)(tmp.cnt);
            gou=tmp.cnt;
            ans+=(t-ave)*(t-ave)*gou;
        }
        t=(double)(m);
        ans/=t;
        printf("Case #%d: %.12f\n",cas,ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sunyutian1998/article/details/83147373
今日推荐