• P2503 [HAOI2006]均分数据 题解(随机贪心)


    题目链接

    题目大意

    把n个数分为m组

    每一组相当于一个新的数,为这组所有数之和

    求这m个数的均方差最小

    (m<=n<=20,2 <=m <= 6)
    image-20210125131719567

    题目思路

    本来我一直是把数大的先放,然后数小的后放,疯狂贪心

    结果还是只能过60%

    其实可以直接随机数组,然后贪心

    每次直接放在最小的那个组里面

    因为显然每个数尽量接近使得均方差最少

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=20+5,inf=0x3f3f3f3f;
    const int eps=1e-6;
    int n,m;
    int a[maxn];
    int zu[7];
    double ans=inf;
    int main(){
        scanf("%d %d",&n,&m); //n<=20 2<=m<=6
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        int _=1e6;
        while(_--){
            memset(zu,0,sizeof(zu));
            random_shuffle(a+1,a+1+n);
            for(int i=1;i<=n;i++){
                int mi=1;
                for(int j=1;j<=m;j++){ //让最小的那组+a[i]
                    if(zu[j]<zu[mi]){
                        mi=j;
                    }
                }
                zu[mi]+=a[i];
            }
            double sum=0,cal=0;
            for(int i=1;i<=m;i++){
                sum+=zu[i];
            }
            sum/=m;
            for(int j=1;j<=m;j++){
                cal+=1.0/m*(zu[j]-sum)*(zu[j]-sum);
            }
            ans=min(ans,sqrt(cal));
        }
        printf("%.2f
    ",ans);
        return 0;
    }
    
    
  • 相关阅读:
    053364
    053363
    oracle导出批量表N行记录
    053362
    053361
    053360
    053359
    053358
    053357
    053356
  • 原文地址:https://www.cnblogs.com/hunxuewangzi/p/14324713.html
Copyright © 2020-2023  润新知