模拟退火 WA 0pts求调
查看原帖
模拟退火 WA 0pts求调
491261
Ghfgvhtt楼主2024/11/22 11:30

rt
代码如下

#include <bits/stdc++.h>
#define down 0.996
using namespace std;
const int N=50;
int n,m,sum[N];
int a[N];
double ave,ans,f[N][N];
double calc()
{
	memset(f,0x3f,sizeof(f));
	f[0][0]=0;
	for(int i=1;i<=n;i++)
		sum[i]=a[i]+sum[i-1];
	for(int i=1;i<=n;i++)
		for(int j=1;j<=i;j++)
			for(int k=0;k<=i-1;k++)
				f[i][j]=min(f[i][j],f[k][j-1]+(sum[i]-sum[k]-ave)*(sum[i]-sum[k]-ave));
	return f[n][m];
}
void SA()
{
	double t=6000;
	while(t>1e-15)
	{
		int x=rand()%n+1,y=rand()%n+1;
		if(x==y) continue;
		swap(a[x],a[y]);
		double nw=calc();
		double ed=nw-ans;
		if(exp(-ed/t)*RAND_MAX>rand()||ed<0)
			ans=nw;
		else
			swap(a[x],a[y]);
		t*=down;
	}
}
void solve()
{
	clock_t s=clock();
	SA();
	clock_t len=clock()-s,limit=CLOCKS_PER_SEC*0.975;
	while(clock()+len<limit) SA();
}
int main() {
	srand(time(0));
	cin>>n>>m;
	ave=0;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		ave+=1.0*a[i];
	}
	ave/=m;
	ans=2e9;
	solve();
	printf("%.2f",sqrt(ans/m));
	return 0;
}
2024/11/22 11:30
加载中...