63pts萌新求助模拟退火[悬赏一关注]
查看原帖
63pts萌新求助模拟退火[悬赏一关注]
593791
_Catluo_楼主2023/2/2 17:12
#include<bits/stdc++.h>
#define int long long 
using namespace std;
int n,ans=1e9,ansx,ansy,nowx,nowy,now;
int a[20005],s[20005],ss[20005];
int sw[20005],S[20005];
int w(int x,int y){
	if(x > y) swap(x, y);
    int now=s[x]*sw[x]+s[y]*(sw[y]-sw[x])+s[n+1]*(sw[n]-sw[y])-S[n];
    if(now<ans)ans=now,ansx=x,ansy=y;
    return now;
}
double Rand(){return (double)rand()/RAND_MAX;}
void SA(){
	double T=1000000;
	while(T>1e-3){
		int x=((int)(nowx+(rand()*2-RAND_MAX)*T)%n+n)%n+1;
		int y=((int)(nowy+(rand()*2-RAND_MAX)*T)%n+n)%n+1;
		int nxt=w(x,y);
		if(nxt<now){
			nowx=x,nowy=y,now=nxt;
		}else if(exp((now-nxt)*1.00/T)>Rand()){
			nowx=x,nowy=y,now=nxt;
		}
		T*=0.995;
	}
}
signed main(){
	srand(time(0));
	scanf("%lld",&n);
	for(int i=1;i<=n;i++)scanf("%lld %lld",&a[i],&ss[i]);
	for(int i=1;i<=n+1;i++){
		s[i]=s[i-1]+ss[i-1];
		sw[i]=sw[i-1]+a[i];
		S[i]=S[i-1]+a[i]*s[i];
	}
	nowx=1,nowy=2;now=w(nowx,nowy);
	while((double)clock()/CLOCKS_PER_SEC<0.95)SA();
	cout<<ans<<endl;
	return 0;
}
2023/2/2 17:12
加载中...