zoukankan      html  css  js  c++  java
  • VK-Cup2017 Wild Card Round 2

    来自FallDream的博客,未经允许,请勿转载,谢谢。


    Cf的Vkcup外卡赛2  上次round2和ditoly翻车了 所以只好来打打了  规则是给一道比较特殊的题目,你要找出较优的解

    University Schedule/大学课程

    有n个学生,m个教授,一周有6天,每天有7节课

    告诉你每个学生这一周要和每个教授上多少节课 但是只有a个教室  也就是同一时间最多只能有a节课

    定义学生和教授的疲劳度  假设一个学生/教授在一天上的第一节课是第x节,最后一节是第y节 那么它的疲劳度是(y-x+3)^2 如果没上课就没有疲劳度

    你要合理的安排上课方案 使得教师和学生的疲劳度之和最小  n,m,a<=60   时间限制10s 有100个pretest 

    一开始写了一个贪心 让学生的课程平均分配   教授不管他 分数有点低... 

    很显然这样并不是特别优秀  而且浪费了非常多的时间 所以考虑换个做法

    时间比较长 所以直接上了模拟退火  贪心之后 随机交换两个课程 另外贪心不一定优 所以加入一些空的课程一起交换 

    卡卡时 效果还可以 最后排到了第8位  实际上还有很多优化的空间 比如记下一天的最早最晚课程 答案 减少计算量等等 

    前几名写的算法不是很懂 (这种比赛的代码都奇奇怪怪 ) 还能找到几个退火的  但是感觉我和ditoly的代码最好看233

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<ctime>
    #define Rep(a,b,c) for(int a=b;a<=c;++a) 
    using namespace std;
    inline int read()
    {
        int x = 0; char ch = getchar();
        while(ch< '0' || ch > '9') ch = getchar();
        while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
        return x;
    }
    
    int n , m , a , Plan[66][66] , Class[66][66] , cnt=0 , Xs_ans[66][7] , Js_ans[66][7] , NewXs[66][7] , NewJs[66][7];
    int ans , Xs[66][7][8] , Js[66][7][8] , Best , Best_Xs[66][7][8];   
    struct Lesson{int xs,js,day,num;}L[100001];
    inline int Sqr(int x){return x * x;}
    
    inline int Calc(int*Schedule)
    {
        int Early = 0 , Last = 0;
        Rep(k ,1 , 7)
            if(Schedule[k])
                (!Early) ? (Early = k) : 0 , Last = k;
        return Early ? Sqr(Last - Early + 3) : 0;
    }
    
    void CalcAns()
    {
        ans = 0;
        Rep(i , 1 , n)
            Rep(j , 1 , 6)
                ans += (Xs_ans[i][j] = Calc( Xs[i][j] ));
        Rep(i , 1 , m)
            Rep(j , 1 , 6)
                ans += (Js_ans[i][j] = Calc( Js[i][j] ));
    }
    
    void Print()
    {
        printf("%d
    " , Best);
        Rep(i , 1 , n)
        {
            puts("");
            Rep(j , 1 , 7) 
            {
                Rep(k , 1 , 6)
                    printf("%d " , Best_Xs[i][k][j]);
                puts("");
            }
        }    
    }
    
    void Copy()
    {
        Best = ans;
        memcpy(Best_Xs , Xs , sizeof(Xs));
    }
    
    inline int Ran()
    {
        return ((rand()<<15)|rand()) % cnt + 1;    
    }
    
    inline double Random()
    {
        return rand() / (double) RAND_MAX;
    }
    
    bool check(int x , int y)
    {
        if( L[x].xs == L[y].xs)
        {
            if(L[x].js == L[y].js) return false;
            if(Js[ L[x].js ][ L[y].day][ L[y].num ] || Js[ L[y].js ][ L[x].day][ L[x].num ]) return false;
            return true;
        }
        if( L[x].js == L[y].js)
        {
            if(Xs[ L[x].xs ][ L[y].day ][ L[y].num ] || Xs[ L[y].xs ][ L[x].day ][ L[x].num ]) return false;
            return true;
        }
        if(Xs[ L[x].xs ][ L[y].day ][ L[y].num ] || Js[ L[x].js ][ L[y].day][ L[y].num ]) return false;
        if(Xs[ L[y].xs ][ L[x].day ][ L[x].num ] || Js[ L[y].js ][ L[x].day][ L[x].num ]) return false;
        return true;
    }
    
    int main()
    {
        srand( 413U );
        n = read(); m = read(); a = read();
        Rep(i , 1 , n) 
            Rep(j , 1 , m)
                Plan[i][j] = read();    
        Rep(i , 1 , n)
        {
            int j = 1 , k = 1;
            for( ; ; )
            { 
                for( ; !Plan[i][j] && j <= m ; ++j);
                if( j > m ) break;
                Rep(l , 1 , 7)
                    if(Class[k][l] < a && !Xs[i][k][l] && !Js[j][k][l])
                    {
                        ++Class[k][l];
                        Xs[i][k][l] = j;
                        Js[j][k][l] = i;
                        --Plan[i][j];
                        L[ ++cnt ] = (Lesson) {i , j , k , l};
                        break;    
                    }
                (++k == 7) ? ( k = 1 ) : 0; 
            } 
        }
        CalcAns(); 
        Copy();
        
        Rep(i , 1 , 6)
            Rep(j , 1 , 7)
                Rep(k , Class[i][j]+1 , a)
                    L[++cnt] = (Lesson) {0 , 0 , i , j};
        
        double Temp = 100 , delta = 0.99; time_t Beg = clock();
        for( ; ; )
        {
            if(clock() - Beg > 9950 ) break;
            Rep(it , 1 , 40000)
            {
                int x = Ran() , y = Ran();
                if(check(x , y))
                {
                    int Newans = ans;
                    Newans -= Xs_ans[ L[x].xs ][ L[x].day ];    
                    Newans -= Xs_ans[ L[y].xs ][ L[x].day ];
                    Newans -= Js_ans[ L[x].js ][ L[x].day ];
                    Newans -= Js_ans[ L[y].js ][ L[x].day ];
                    if( L[x].day != L[y].day )
                    Newans -= Xs_ans[ L[x].xs ][ L[y].day ],
                    Newans -= Xs_ans[ L[y].xs ][ L[y].day ],
                    Newans -= Js_ans[ L[x].js ][ L[y].day ],
                    Newans -= Js_ans[ L[y].js ][ L[y].day ];
                    
                    Xs[ L[x].xs ][ L[x].day ][ L[x].num ] = 0;
                    Xs[ L[y].xs ][ L[y].day ][ L[y].num ] = 0;
                    Js[ L[x].js ][ L[x].day ][ L[x].num ] = 0;
                    Js[ L[y].js ][ L[y].day ][ L[y].num ] = 0;
                    
                    Xs[ L[x].xs ][ L[y].day ][ L[y].num ] = L[x].js;
                    Xs[ L[y].xs ][ L[x].day ][ L[x].num ] = L[y].js;
                    Js[ L[x].js ][ L[y].day ][ L[y].num ] = L[x].xs;
                    Js[ L[y].js ][ L[x].day ][ L[x].num ] = L[y].xs;
                    
                    Newans += (NewXs[ L[x].xs ][ L[x].day ] = Calc(Xs[ L[x].xs ][ L[x].day ]));    
                    Newans += (NewXs[ L[y].xs ][ L[x].day ] = Calc(Xs[ L[y].xs ][ L[x].day ]));
                    Newans += (NewJs[ L[x].js ][ L[x].day ] = Calc(Js[ L[x].js ][ L[x].day ]));
                    Newans += (NewJs[ L[y].js ][ L[x].day ] = Calc(Js[ L[y].js ][ L[x].day ]));
                    if( L[x].day != L[y].day )
                    Newans += (NewXs[ L[x].xs ][ L[y].day ] = Calc(Xs[ L[x].xs ][ L[y].day ])),
                    Newans += (NewXs[ L[y].xs ][ L[y].day ] = Calc(Xs[ L[y].xs ][ L[y].day ])),
                    Newans += (NewJs[ L[x].js ][ L[y].day ] = Calc(Js[ L[x].js ][ L[y].day ])),
                    Newans += (NewJs[ L[y].js ][ L[y].day ] = Calc(Js[ L[y].js ][ L[y].day ]));
                    
                    if(Newans < ans || Random() < exp((ans-Newans)/Temp)) 
                    {
                        if(Newans < ans)  ans = Newans , Copy();    
                        ans = Newans;
                        swap(L[x].day , L[y].day);
                        swap(L[x].num , L[y].num);
                        Xs_ans[ L[x].xs ][ L[x].day ] = NewXs[ L[x].xs ][ L[x].day ];    
                        Xs_ans[ L[y].xs ][ L[x].day ] = NewXs[ L[y].xs ][ L[x].day ];
                        Js_ans[ L[x].js ][ L[x].day ] = NewJs[ L[x].js ][ L[x].day ];
                        Js_ans[ L[y].js ][ L[x].day ] = NewJs[ L[y].js ][ L[x].day ];
                        if( L[x].day != L[y].day )
                        Xs_ans[ L[x].xs ][ L[y].day ] = NewXs[ L[x].xs ][ L[y].day ],
                        Xs_ans[ L[y].xs ][ L[y].day ] = NewXs[ L[y].xs ][ L[y].day ],
                        Js_ans[ L[x].js ][ L[y].day ] = NewJs[ L[x].js ][ L[y].day ],
                        Js_ans[ L[y].js ][ L[y].day ] = NewJs[ L[y].js ][ L[y].day ];
                    }
                    else
                    {
                        Xs[ L[x].xs ][ L[y].day ][ L[y].num ] = 0;
                        Xs[ L[y].xs ][ L[x].day ][ L[x].num ] = 0;
                        Js[ L[x].js ][ L[y].day ][ L[y].num ] = 0;
                        Js[ L[y].js ][ L[x].day ][ L[x].num ] = 0;
                    
                        Xs[ L[x].xs ][ L[x].day ][ L[x].num ] = L[x].js;
                        Xs[ L[y].xs ][ L[y].day ][ L[y].num ] = L[y].js;
                        Js[ L[x].js ][ L[x].day ][ L[x].num ] = L[x].xs;
                        Js[ L[y].js ][ L[y].day ][ L[y].num ] = L[y].xs;    
                        
                    }   
                }
            }
            Temp *= delta;
        }
        Print();
        return 0;
    }
  • 相关阅读:
    在 Linux 上如何挂载 qcow2 磁盘镜像
    CentOS ISO 下载地址
    构建ceph deb 安装包
    ceph 源码安装 configure: error: "Can't find boost spirit headers"
    sudo: 没有终端存在,且未指定 askpass 程序
    ubuntu14.04 下出现 libmysqlclient.so.20 找不到问题
    binary-tree-postorder-traversal leetcode C++
    binary-tree-preorder-traversal leetcode C++
    candy leetcode C++
    clone-graph leetcode C++
  • 原文地址:https://www.cnblogs.com/FallDream/p/VKCupWildCard2.html
Copyright © 2011-2022 走看看