社区讨论

萌新求助模拟退火

P3878[TJOI2010] 分金币参与者 2已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@lod2cii4
此快照首次捕获于
2023/10/30 23:37
2 年前
此快照最后确认于
2023/11/05 09:55
2 年前
查看原帖
Rt,最多50分,提交了三页了
CPP
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
int n;
long long a[35];
long long ans;
double t;
const double beginT=5000,deltaT=0.9112,endT=1e-10;
int energy(){
	long long res1=0,res2=0;
	int mid=(1+n)>>1;
	for(int i=1;i<=mid;i++){
		res1+=a[i];
	}
	for(int i=mid+1;i<=n;i++){
		res2+=a[i];
	}
	return abs(res1-res2);
}
void SA(){
	t=beginT;
	while(t>endT){
		int x=rand()%n+1;
		int y=rand()%n+1;
		swap(a[x],a[y]);
		long long now=energy();
		if(now<=ans){
			ans=now;
		}else if(exp((ans-now)/t)<rand()/RAND_MAX){
			swap(a[x],a[y]);
		}
		t*=deltaT;
	}
}
void solve(){
	int cnt=1000;
	ans=0x3f3f3f3f;
	while(cnt--){
		SA();
	}
}
int main(){
	srand(rand());
	srand(rand()+20060907);
	srand(rand());
	int t;
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
		}
		solve();
		printf("%lld\n",ans);
	}
	return 0;
} 

回复

3 条回复,欢迎继续交流。

正在加载回复...