模拟退火求助
查看原帖
模拟退火求助
600442
DreamSoarUpward楼主2022/12/16 17:46

照着第一篇题解的思路写的,不知道哪错了。

#include<bits/stdc++.h>
#define minn(a,b) a>b?b:a
#define N 105
using namespace std;
int n,m;
int a[N],s[N];
double ans=1e18;
int f[N][N];
int tmp;
const double delta=0.99;
double cal(){
  	memset(f,127,sizeof(f));
  	for(int i=1;i<=n;i++)
	  	s[i]=s[i-1]+a[i];
	f[0][0]=0;
	for(int i=1;i<=n;i++)
	    for(int j=1;j<=i;j++)
		    for(int k=0;k<i;k++)
		    	f[i][j]=minn(f[i][j],f[k][j-1]+(s[i]-s[k]-tmp)*(s[i]-s[k]-tmp));
	ans=minn(ans,f[n][m]);
	return f[n][m];
}
double Rand(){return rand()%100000/100000.00;}
void SA(){
	double T;
	T=1e4;
  	while(T>1e-3){
      	int x=rand()%n+1;
	  	int y=rand()%n+1;
      	if(x==y)
		  	continue;
      	swap(a[x],a[y]);
      	double nw=cal();
      	double Delta=nw-ans;
	    if(Delta<0)
			ans=nw;
		else if(exp(-Delta)/T>Rand())
			ans=nw;
	    else
			swap(a[x],a[y]);
      	T*=delta;
    }
  	for(int i=1;i<=(int)1e4;i++){
      	int x=rand()%n+1;
	  	int y=rand()%n+1;
      	if(x==y) 
	  		continue;
      	swap(a[x],a[y]);
		cal();
		swap(a[x],a[y]);
    }
}
void solve(){while((double)clock()/CLOCKS_PER_SEC<0.75) SA();}
int main(){
	srand(time(0));
  	srand(rand());
  	srand(rand());
  	cin>>n>>m;
  	for(int i=1;i<=n;i++) cin>>a[i];
  	for(int i=1;i<=n;i++) tmp+=1.0*a[i]/m;
  	cal();
  	cout<<fixed<<setprecision(2)<<ans/m<<endl;
  	return 0;
}
2022/12/16 17:46
加载中...