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\n" , 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;
}
posted @ 2017-05-04 19:27  FallDream  阅读(323)  评论(0编辑  收藏  举报