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;
    }
  • 相关阅读:
    Python 操作 Azure Blob Storage
    @private、@protected与@public三者之间的区别
    iOS设计模式
    NSMapTable、NSHashTable与NSPointerArray的封装
    iOS设计模式
    用UITextView加载rtfd文件
    UIWebView如何加载本地图片
    [翻译] BezierString
    [翻译] AYVibrantButton
    用NSOperation写下载队列
  • 原文地址:https://www.cnblogs.com/Cptraser/p/8670334.html
Copyright © 2011-2022 走看看