zoukankan      html  css  js  c++  java
  • bzoj2428: [HAOI2006]均分数据

    垃圾bzoj本机AC提交WA,精A

    %你退火可解

    因为n很小所以我们可以降温慢点,为了更优我们先在开始的时候选择一个数贪心地放到总和最小地那一组

    然后就是不停换随机种子T_T

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    double sqr(double x){return x*x;}
    double drand(){return double(rand()%10000)/10000.0;}
    
    int n,m,p[30];double a[30],mmin;
    double sum[30];
    double calc()
    {
        memset(sum,0,sizeof(sum));
        for(int i=1;i<=n;i++)sum[p[i]]+=a[i];
        
        double ave=0;
        for(int i=1;i<=m;i++)ave+=sum[i];
        ave/=double(m);
            
        double ret=0;
        for(int i=1;i<=m;i++)ret+=sqr(ave-sum[i]);
        ret=sqrt(ret/(double)m);
        if(ret<mmin)mmin=ret;
        return ret;
    }
    void annealing()
    {
        double T=1000000.0;
    
        while(T>1)
        {
            double k1=calc();
            
            int pp=1;
            for(int i=1;i<=m;i++)
                if(sum[i]<sum[pp])pp=i;
                
            int x=rand()%n+1,np;
            while(p[x]==pp){x++;if(x==n+1)x=1;}
            
            np=p[x],p[x]=pp;
            double k2=calc();
            
            if(k1>k2||exp((k1-k2)/T)>drand());
            else p[x]=np;
            
            T*=0.9997;
        }
        
        while(T>0.0001)
        {
            int x=rand()%n+1,pp=rand()%m+1,np;
            if(pp==p[x]){pp++;if(pp==m+1)pp=1;}
            
            double k1=calc();
            np=p[x],p[x]=pp;
            double k2=calc();
            
            if(k1>k2||exp((k1-k2)/T)>drand());
            else p[x]=np;
            
            T*=0.9997;
        }
        
        for(int i=1;i<=1000;i++)
        {
            int x=rand()%n+1,pp=rand()%m+1,np;
            if(pp==p[x]){pp++;if(pp==m+1)pp=1;}
            
            double k1=calc();
            np=p[x],p[x]=pp;
            double k2=calc();
            p[x]=np;
        }
    }
    
    int main()
    {
        srand(25424);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%lf",&a[i]), p[i]=rand()%m+1;
        random_shuffle(a+1,a+n+1);
        
        mmin=calc();
        annealing();
        printf("%.2lf",mmin);
        return 0;
    }
  • 相关阅读:
    iPhone开发教程之retain/copy/assign/setter/getter
    关于block使用的5点注意事项
    Block的引用循环问题 (ARC & non-ARC)
    浅谈iOS中MVVM的架构设计与团队协作
    JS学习笔记(不断更新)
    神经网络介绍
    JAVA WEB WITH IDEA
    百度地图标注多个点
    脑筋急转弯——Google 面试
    决策树分类器
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10025760.html
Copyright © 2011-2022 走看看