zoukankan      html  css  js  c++  java
  • 「JOISC 2020 Day4」传奇团子师傅 (假模拟退火)

    「JOISC 2020 Day4」传奇团子师傅 (假模拟退火)

    感觉每次想写模拟退火,调着调着就不知道变成什么东西了

    首先是分析原图,每个方案对应选择三个点,不同的方案之间显然存在排斥关系

    将这些关系建立成边,问题就转化为一个 一般图最大独立集 问题

    这怎么搞得定。。

    因此考虑退火,每次操作随机选择一个点,检查周围的点是否选择,数一下如果自己被选,要弹掉的点的个数

    同普通的退火,一开始温度高不停随机

    到了后面就直接变成 选择答案不劣的方案(也就是交换两个点),事实证明这样的效率比较高

    但是直接随机容易随机到选过的点,需要稍微加速一下

    具体的,退火每若干次为一轮,每轮随机一个排列

    在排列中从左到右找到前面(L)个未选点,然后在(L)个点中随机若干次进行决策

    我是直接暴力bitset存答案的,但是效率好像还可以

    因为是跑一个点调一次参数的,前面的代码都没存。。。

    tips:代码对于不同数据需要修改前面三行的常量

    const int N=510,M=N*N/2,INF=1e9+10;
    const char infile[]="5.in",outfile[]="output_05.txt";
    const int MAX=48620;
    
    int n,m,C;
    char s[N][N];
    int chk(char x){ return x=='P' || x=='G'; }
    struct Node{
        int x,y,t;
    } R[M];
    bitset <M> Ansmap,Nowmap;
    int ans,now;
    
    int z[4][2]={{0,1},{1,0},{-1,-1},{-1,1}};
    char S[]="-|\/";
    vector <int> G[N][N],E[M];
    
    struct Naive_Simulator{
        ~Naive_Simulator(){
            cerr<<"!"<<endl;
            rep(i,1,C) if(Ansmap[i]) s[R[i].x][R[i].y]=S[R[i].t];
            rep(i,1,n) puts(s[i]+1);
        }
        int P[M],D[M],F[M],PC,counter,lst,L;
        void Work(db T,db d,db End,int delta) {
            while(T>End && ans<MAX) {
                if(++counter%4000==0) {
                    cerr<<ans<<' '<<T<<endl;
                }
                if(counter%500==0) random_shuffle(D+1,D+C+1),lst=1;
                PC=0;
                rep(i,lst,C) if(!Nowmap[D[i]]) {
                    P[++PC]=D[i];
                    lst=i;
                    if(PC>=L) break;
                }
                if(PC<L) {
                    lst=1;
                    PC=0;
                    rep(i,lst,C) if(!Nowmap[D[i]]) {
                        P[++PC]=D[i];
                        lst=i;
                        if(PC>=L) break;
                    }
                }
                rep(kase,1,50) {
                    int u,v;
                    u=P[rand()%PC+1],v=P[rand()%PC+1];
                    if(u==v || Nowmap[u]) {
                        kase--;
                        continue;
                    }
                    int cnt=0;
                    for(int v:E[u]) cnt+=Nowmap[v];
                    if(cnt-delta<=T) {
                        Nowmap[u]=1;
                        for(int v:E[u]) Nowmap[v]=0;
                        now+=1-cnt;
                    } 
                    if(kase%5==0 && now>ans) ans=now,Ansmap=Nowmap;
                }
                T*=d;
            }
        }
        void Simulate(){
            //srand(114514);
            //srand(1919810);
            srand(time(NULL));
            now=0,Nowmap.reset();
            counter=0,lst=1,L=200;
            rep(i,1,C) D[i]=i;
            rep(kase,1,10) Work(2,0.95,1e-2,1);
            Work(0.99,0.99993,1e-8,2);
            Nowmap=Ansmap,now=ans;
            Work(0.99,0.99999,0,1);
            return;
        }
    
        Naive_Simulator(){
            freopen(infile,"r",stdin),freopen(outfile,"w",stdout);
            n=rd(),m=rd();
            rep(i,1,n) scanf("%s",s[i]+1);
            rep(i,1,n) rep(j,1,m) if(!chk(s[i][j])) {
                s[i][j]='W';
                rep(d,0,3) if(chk(s[i+z[d][0]][j+z[d][1]]) && chk(s[i-z[d][0]][j-z[d][1]]) && s[i+z[d][0]][j+z[d][1]]!=s[i-z[d][0]][j-z[d][1]]) {
                    R[++C]=(Node){i,j,d};
                    G[i][j].pb(C);
                    G[i+z[d][0]][j+z[d][1]].pb(C);
                    G[i-z[d][0]][j-z[d][1]].pb(C);
                }
            }
            rep(i,1,n) rep(j,1,m) rep(k,0,G[i][j].size()-1) rep(l,k+1,kend) {
                E[G[i][j][k]].pb(G[i][j][l]);
                E[G[i][j][l]].pb(G[i][j][k]);
            }
            Simulate();
        }
    } Solver;
    
    int main(){ ; }
    
  • 相关阅读:
    Ubuntu10.04搭建linux-0.11编译环境(1.bochs安装和使用)
    Linux 0.11内核编译和bochs上的实验环境的搭建
    64位Linux的内核和用户地址空间
    2012年计算机考研大纲——操作系统
    【27.34%】【codeforces 611D】New Year and Ancient Prophecy
    【14.94%】【codeforces 611E】New Year and Three Musketeers
    【53.57%】【codeforces 610C】Harmony Analysis
    【42.49%】【hdu 1542】Atlantis(线段树扫描线简析)
    【49.23%】【hdu 1828】Picture
    【20.51%】【codeforces 610D】Vika and Segments
  • 原文地址:https://www.cnblogs.com/chasedeath/p/14549178.html
Copyright © 2011-2022 走看看