关于输入&退火
查看原帖
关于输入&退火
639198
Steve_xh楼主2024/12/4 12:31

以下代码是 82pts 的。

#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef long long ll;
const int MAXN=25,mod=998244353,inf=0x3f3f3f3f;
int n,w,a[MAXN],b[MAXN],f[MAXN],s[MAXN];
int check(){
    for(int i=1;i<=n;i++){
        f[i]=f[i-1]+1;
        s[i]=s[i-1]+b[i];
        for(int j=i-1;j>=0;j--){
            if(s[i]-s[j]>=w)
                break;
            f[i]=min(f[i],f[j]+1);
        }
    }
    return f[n];
}
int ans=MAXN;
void init(){
    for(int i=1;i<=n;i++)
        b[i]=a[i];
}
const double Tend=1e-11,Tdelta=0.99;
mt19937 rnd(time(nullptr)^random_device{}());
int sa(){
    init();
    int reans=check();
    for(double T=1.1e5;T>Tend;T*=Tdelta){
        int x,y;
        while((x=uniform_int_distribution<>(1,n)(rnd))==(y=uniform_int_distribution<>(1,n)(rnd)))
            ;
        swap(b[x],b[y]);
        int newans=check();
        if(newans<=reans)
            reans=newans;
        else if(exp((double)(reans-newans)/T)>=uniform_real_distribution<>(0,1)(rnd))
            reans=newans;
        else
            swap(b[x],b[y]);
    }
    return reans;
}
signed main(){
    cin.tie(nullptr)->sync_with_stdio(false);
    cin>>n>>w;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    while(clock()<995000)
        ans=min(ans,sa());
    cout<<ans;
    return 0;
}

无论如何调参就是卡在这个分数,然后看了眼题解,发现退火题解有一句 w*=1.05,我加上后就过了。求问这是什么原理。/yiw

2024/12/4 12:31
加载中...