洛谷P1559 运动员最佳匹配问题 题解 模拟退火

题目链接:https://www.luogu.com.cn/problem/P1559

模拟退火模板题。

实例程序:

#include <bits/stdc++.h>
using namespace std;
int n, P[22][22], Q[22][22], p[22];
long long ans;

long long cal() {
    long long sum = 0;
    for (int i = 0; i < n; i++) {
        int j = p[i];
        sum += 1ll * P[i][j] * Q[j][i];
    }
    ans = max(ans, sum);
    return sum;
}

void sa() {
    random_shuffle(p, p+n);
    for (double t = 1e4; t >= 1e-4; t *= 0.993) {
        long long cur = cal();
        int x = rand() % n, y = (x + 1 + rand() % (n-1)) % n;
        swap(p[x], p[y]);
        long long tmp = cal();
        double dt = tmp - cur;
        if (exp(-dt / t) < (double) rand() / RAND_MAX) {
            ;
        }
        else
            swap(p[x], p[y]);
    }
}

int main() {
    srand(time(NULL));
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            scanf("%d", &P[i][j]);
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            scanf("%d", &Q[i][j]);
    for (int i = 0; i < n; i++)
        p[i] = i;
    for (int i = 0; i < 1000; i++)
        sa();
    printf("%lld\n", ans);
    return 0;
}
posted @ 2026-04-29 13:35  quanjun  阅读(11)  评论(0)    收藏  举报