萌新求助模拟退火TLE
查看原帖
萌新求助模拟退火TLE
226113
火羽白日生楼主2020/8/18 09:00

总是TLE最后四个点

我看第二篇题解的大佬SA了1000次都可

我就50次就T飞了 改到10次也T飞

救救孩子

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <stdlib.h>
#include <algorithm>
#include <map>
#include <queue>
#include <vector>

//#pragma GCC optimize(2)  //吸氧
//#pragma GCC optimize(3,"Ofast","inline")  //吸臭氧

typedef long long ll;
typedef unsigned long long ull;
using namespace std;

inline int read(){
    char ch=getchar();
    int x=0,w=1;
    while(ch<'0'||ch>'9'){
        if(ch=='-')
            w=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=(x<<3)+(x<<1)+(ch^48);
        ch=getchar();
    }
    return x*w;
}

int T,n,ans=1e9,val[105];

int calc(){
    int sum1=0,sum2=0;
    for(int i=1;i<=(n+1)/2;i++)
        sum1+=val[i];
    for(int i=(n+1)/2+1;i<=n;i++)
        sum2+=val[i];
    return abs(sum1-sum2);
}

void simulate_anneal(){
    double t=3000.0,delta=0.996;
    while(t>1e-15){
        int x=rand()%n+1;
        int y=rand()%n+1;
        if(x==y) continue;
        swap(val[x],val[y]);
        int now_ans=calc();
        int now_delta=now_ans-ans;
        if(now_delta<0)
            ans=now_ans;
        else if(exp(-now_delta/t)*RAND_MAX<rand())
            swap(val[x],val[y]);
        t*=delta;
    }
}
void work(){
    for(int i=1;i<=50;i++)
        simulate_anneal();
}

int main(int argc, const char * argv[]) {
    srand(time(NULL));
    srand(rand());
    srand(rand());
    T=read();
    for(int i=1;i<=T;i++){
        n=read();
        for(int j=1;j<=n;j++)
            val[j]=read();
        work();
        printf("%d\n",ans);
        ans=1e9;
    }
    return 0;
}

2020/8/18 09:00
加载中...