zoukankan      html  css  js  c++  java
  • BZOJ2428_均分数据_KEY

    题目传送门

    这道题可以用C++的random_shuffle屮过去。

    random数列插入顺序,每次都插入数值和最小的那一组。

    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    int N,M,a[25];
    double ave,ans=2e9,t[25];
    
    double get()
    {
        double tot=0;
        memset(t,0,sizeof t);
            for(int i=1;i<=N;i++){
                int d,mx=2e9;
                for(int j=1;j<=M;j++)if(t[j]<mx)mx=t[j],d=j;
                t[d]+=a[i];
            }
            for(int i=1;i<=M;i++)
                tot+=(ave-t[i])*(ave-t[i]);
        return tot;
    }
    
    int main()
    {
        srand(100000007);
        scanf("%d%d",&N,&M);
            for(int i=1;i<=N;i++)scanf("%d",&a[i]),ave+=a[i];ave/=M;
            for(int i=1;i<=600000;i++){
                random_shuffle(a+1,a+N+1);
                ans=min(ans,get());
            }
        printf("%.2lf",sqrt(ans/M));
        return 0;
    }
    random_shuffle

    这道题也可以用模拟退火。

    设定一个初始温度,然后降温,降温的同时如果大于某个你设定的温度,即当前状态不稳定,进行贪心。

    反之为稳定可以随机一个放到随机一个组里。

    code:

    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    int N,M,w[25],S=52867;
    double ans,res=2e9,t[25],ave,a[25];
    
    void work(int x,int y)
    {
        t[w[x]]-=a[x];
        t[y]+=a[x];
        w[x]=y;
    }
    
    double get()
    {
        double tot=0;
        for(int i=1;i<=M;i++)
            tot+=(ave-t[i])*(ave-t[i]);
        return tot;
    }
    
    int main()
    {
        scanf("%d%d",&N,&M);
            for(int i=1;i<=N;i++)
                scanf("%lf",&a[i]),ave+=a[i];
        ave/=M;
        srand(12254687);
        while(S--){
            memset(t,0,sizeof t);
            memset(w,0,sizeof w);
                for(int i=1;i<=N;i++)
                    t[w[i]=rand()%M+1]+=a[i];
            ans=get();
                for(double Tempr=15000;Tempr>1;Tempr*=0.812){
                    int x=rand()%N+1,y=1,bef;
                    if(Tempr<100)y=rand()%M+1;
                    else for(int i=2;i<=M;i++)if(t[y]>t[i])y=i;
                    bef=w[x];
                    work(x,y);
                    double now=get();
                    if(now<ans||Tempr>rand()%15000)ans=now;
                    else work(x,bef);
                }
            res=min(res,ans);
        }
        printf("%.2lf",sqrt(res/M));
        return 0;
    }
  • 相关阅读:
    C/C++多文件之间的变量定义
    PKU POJ 2186 Popular Cows 强连通分量
    重载函数
    ZOJ 2763 Prison Break
    201357 训练赛总结
    hdu 4467 Graph 构造
    201356 训练赛总结
    201353 NEERC 2012, Eastern subregional contest
    2013512 CF 183 总结
    一道动态规划
  • 原文地址:https://www.cnblogs.com/Cptraser/p/8670334.html
Copyright © 2011-2022 走看看