用模拟退火写了 NOIP2021 方差,代码如下:
#include<bits/stdc++.h>
using namespace std;
#define N 10003
#define LL long long
#define INF 0x3f3f3f3f3f3f3f3f
int n,a[N],d[N];
LL ans=INF;
LL calc(){
for(int i=1;i<=n;++i)
a[i]=a[i-1]+d[i];
LL pfh=0,hpf=0;
for(int i=1;i<=n;++i)
pfh+=a[i]*a[i],hpf+=a[i];
return n*pfh-hpf*hpf;
}
void month(){
LL lst=calc();
ans=min(ans,lst);
for(double t=1e3;t>1e-7;t*=0.99){
LL llst=lst;
int u=rand()%(n-1)+2,v=rand()%(n-1)+2;
swap(d[u],d[v]);
LL y=calc();
ans=min(ans,y),lst=y;
double del=y-llst;
if(exp(-del/t)<(double)rand()/RAND_MAX)
swap(d[u],d[v]),lst=llst;
}
}
int main(){
freopen("variance.in","r",stdin);
freopen("variance.out","w",stdout);
scanf("%d",&n);
if(n==1) return puts("0"),0;
srand(time(0));
for(int i=1;i<=n;++i)
scanf("%d",&a[i]),
d[i]=a[i]-a[i-1];
while((double)clock()/CLOCKS_PER_SEC<0.85)
month();
printf("%lld\n",ans);
return 0;
}
windows 下能过编,交到洛谷也能正常评测(而且退了个 88pts),在自己电脑 Linux 模拟机上也没有任何问题,但是在我们教练的 Linux 评测机上 CE,这是为啥