求调退火参数
查看原帖
求调退火参数
526519
Aisaka_Taiga楼主2023/10/28 09:19

rt,思路是把 n−1n-1 个差分出来的值随机打乱然后计算方差,目前最高只有80.


/*
 * @Author: Aisaka_Taiga
 * @Date: 2023-10-28 08:32:21
 * @LastEditTime: 2023-10-28 09:17:22
 * @LastEditors: Aisaka_Taiga
 * @FilePath: \Desktop\P7962.cpp
 * The heart is higher than the sky, and life is thinner than paper.
 */
#include <bits/stdc++.h>

#define int long long
#define DB double
#define N 1000100

using namespace std;

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

int n, a[N], b[N], c[N], ans;

inline int calc()
{
    int res = 0, t = 0, sum = 0;
    for(int i = 1; i <= n; i ++)
    {
        t += c[i];
        sum += t;
        res += t * t;
    }
    res = res * n - sum * sum;
    return res;
}

inline void SA()
{
    DB T = 1e4;
    while(T >= 1e-5)
    {
        int x = rand() % (n - 1) + 2, y = rand() % (n - 1) + 2;
        if(x == y) continue;
        swap(c[x], c[y]);
        int res = calc();
        int d = res - ans;
        T *= 0.998;
        if(d < 0) ans = res;
        else if(exp(-d / T) * RAND_MAX > rand()) {continue; cout << " ? " << endl;}
        else swap(c[x], c[y]);
    }
    return ;
}

signed main()
{
    srand(time(0));
    n = read();
    for(int i = 1; i <= n; i ++) a[i] = read();
    for(int i = 1; i <= n; i ++)
        c[i] = b[i] = a[i] - a[i - 1];
    ans = calc();
    // cout << "ASN : " << ans << endl;
    while((DB)clock() / CLOCKS_PER_SEC < 0.9) SA();
    cout << ans << endl;
    return 0;
}
2023/10/28 09:19
加载中...