rt,萌新刚学模拟退火,目前第 17 个点要么 TLE 要么跑不出答案。
有大佬帮忙调参/加一些技巧吗,非常感谢。
#include<bits/stdc++.h>
using namespace std;
#define maxn 1000005
int n,a[maxn],s,num;
bool used[maxn];
int main(){
mt19937 rd(time(NULL));
int t,tt;
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin>>t;
tt=t;
while(tt--){
s=num=0;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int tim=1;tim<20000000/t;tim++){
double t=50000,tl=0.01;
while(t>tl){
int pos=rd()%n+1;
if(used[pos]){
if((abs(s)>abs(s-a[pos])&&num!=1)||((double)(rd()%100000001)/100000000.0)<exp(-(double)(abs(s-a[pos])-abs(s))/t)){
used[pos]=false;
s-=a[pos];
num--;
}
}
else{
if(!num||abs(s)>abs(s+a[pos])||((double)(rd()%100000001)/100000000.0)<exp(-(double)(abs(s+a[pos])-abs(s))/t)){
used[pos]=true;
s+=a[pos];
num++;
}
}
if(!s&&num){
break;
}
t*=0.97;
}
if(!s&&num){
break;
}
}
assert(!s);
cout<<num<<'\n';
for(int i=1;i<=n;i++){
if(used[i]){
cout<<i<<' ';
}
}
cout<<'\n';
for(int i=1;i<=n;i++){
used[i]=false;
}
}
return 0;
}