10pts退火求调
查看原帖
10pts退火求调
771117
lts080812楼主2024/11/27 21:18

简单退火显然可过

#include<bits/stdc++.h>
using namespace std;
#define down 0.99998
int n,m;
#define forr for(register int i=1;i<=m;i++)
int ma[130],mans[130],ans,c,p[360];

int answer()
{
	int anss=p[1],now=1;
	forr now+=ma[i],anss+=p[now];
	return anss;
}

void sa()
{
	double t=1e5;
	int na=ans;
	int lastna=na;
	forr ma[i]=mans[i];
	while(t>=1e-5)
	{
		int x=(rand()%m)+1,y=(rand()%m)+1;
		if(ma[x]==ma[y])continue;
		swap(ma[x],ma[y]);
		int nna=answer();
		int del=nna-lastna;
		if(del>0)
		{
			forr mans[i]=ma[i];
			ans=na=nna;
		}else if(exp(-del/t)*RAND_MAX>rand())
			na=nna;
		else swap(ma[x],ma[y]);
		t*=down;
	}
}

void solve()
{
	forr mans[i]=ma[i];
	ans=answer();
	sa();sa();sa();
}

int main()
{
	srand(2101142);
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		cin>>p[i];
	forr
		cin>>ma[i];
	solve();
	cout<<ans<<endl;
	return 0;
}
2024/11/27 21:18
加载中...