模拟退火<P2210>

做宝藏时被某L大佬强制(bushi)开题,又经某C大佬教育,终于学会了如何模gao拟ji退pian火fen。
调参真快乐!suffer from the great happiness!

#include<bits/stdc++.h>
using namespace std;
int n,f[13][3],pos[13],ans=0x7f7f7f;
int payy(){
    int now= 0;
    for(int i= 1; i <= n; i++) {
        for(int j= 0; j < 3; j++) {
            now+= abs(pos[i] - pos[f[i][j]]);
        }
    }
    return now;
}
const double StartT=1e5,EndT=1e-12,ChangeT=0.998;
void SA(int t) {
    int x, y, now;
    while(t--) {
        for(double T=StartT; T >EndT; T*= ChangeT) {
            do {
                x= rand() % n + 1;
                y= rand() % n + 1;
            } while(x == y);
            swap(pos[x], pos[y]);
            now=payy();
            if(now<=ans) {
                ans=now;

            }
            else if(exp((ans - now)/T)>(double)rand()/RAND_MAX) {
                swap(pos[x], pos[y]);
            }
        }
    }
    return;
}
int main() {
    srand(time(0));
    scanf("%d",&n);
    for(int i= 1; i <= n; i++) {
        scanf("%d%d%d",&f[i][0],&f[i][1],&f[i][2]);
        pos[i]=i;
    }
    SA(270);
    cout<< ans / 2 << '
';
    return 0;
}
原文地址:https://www.cnblogs.com/DeadApple/p/11823182.html