The sol to coin(SA)
The sol to coin(SA)
https://www.luogu.com.cn/problem/P3878
这题是模拟退火的板子。
虽然一般的模拟退火不能支持多测的题目,因为时间可能卡不好,但在没有办法的办法下(其实就是乱搞),可以自己酌情设置SA的参数和SA的次数。
AC_code
#include<random>
#include<algorithm>
#define Ying using
#define AK namespace
#define IOI std;
#define By return
#define JX_JOKER 0;
#define int long long
#define FOR(i,_l,_r) for(int i=(_l);i<=(_r);i++)
#define il inline
Ying AK IOI
il int read(){
int x=0,f=1;char c=getchar_unlocked();
while(c<'0'||c>'9'){
if(c=='-') f=-1;
c=getchar_unlocked();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0';
c=getchar_unlocked();
}
return x*f;
}
il void print(int x){
if(x<0) putchar('-'),x=-x;
if(x>9) print(x/10);
putchar(x%10+'0');
}
const int N=35;
int a[N];
int l[N];int r[N];
int T;
int n;
int s1;
int s2;
int dis;
int ans;
void SA(){
srand(20090404);
double T_begin=2009.0404,T_end=1e-15;
for(;T_begin>=T_end;T_begin*=0.951){
int p=rand()%(n/2)+1;
int q=rand()%(n/2)+1;
int st=dis;
int S1=s1;
int S2=s2;
s1=s1-l[p]+r[q];
s2=s2-r[q]+l[p];
swap(l[p],r[q]);
dis=abs(s1-s2);
if(dis<ans) ans=dis;
else if(exp(-(dis-ans)/T_begin)*RAND_MAX<rand()){
swap(l[p],r[q]);
dis=st;s1=S1;s2=S2;
}
}
}
signed main(){
#ifndef ONLINE_JUDGE
freopen("coin.in","r",stdin);
freopen("coin.out","w",stdout);
#endif
T=read();
while(T--){
s1=0;s2=0;
n=read();
FOR(i,1,n) a[i]=read();
if(n&1) a[++n]=0;
//sort(a+1,a+n+1);
FOR(i,1,n/2) l[i]=a[i];
FOR(i,1,n/2) s1+=l[i];
FOR(i,1,n/2) r[i]=a[i+n/2];
FOR(i,1,n/2) s2+=r[i];
dis=abs(s1-s2);
ans=dis;
FOR(i,1,600) SA();
print(ans);puts("");
}
By JX_JOKER
}