题解:UVA1476 Error Curves 使用 SA 解决

我们来分析一下这个题。

就这么说,虽然你能够用这个那个数学方法来证明出这是一个单峰函数,但是很多时候如果没有“三分”这个标签,你压根就想不出来这道题是单峰函数。

所以我们可以用模拟退火来解决这道题(调参调了一天)。

这道题因为较为简单,所以可以设置较为激进的降温策略。初始温度设置一个最平常的 4000 就可以了。

其他的就跟 SA 的模板是差不多的了。

AC 代码:

#include <bits/stdc++.h>
using namespace std;
const double down=0.9943; // 可以设置激进一点的降温速度
int n;
struct node{
	double x,y,w;
}a[10005];
double dx,now;
double energy(double x)
{
	double tot=-1e20; // 注意 f(x) 可能为负数
	for(int i=1; i<=n; i++)
	{
		tot=max(tot,a[i].x*x*x+a[i].y*x+a[i].w);
	}
	return tot;
}
void SA()
{
	double t=4000;
	while(t>1e-17)
	{
		double tx=dx+(rand()*2-RAND_MAX)*t;
		if(tx<0) tx=(rand()%100);
		if(tx>1000) tx=(1000);
		
      	double temp=energy(tx);
      	double delte=temp-now;
      	if(delte<0)
      	{
      		dx=tx;
      		now=temp;
		  }
		else if(exp(-delte/t)*RAND_MAX>rand())
		{
			dx=tx;
		}
		t*=down;
	}
}
void sjk()
{
	cin>>n;
	for(int i=1; i<=n; i++)
	{
		cin>>a[i].x>>a[i].y>>a[i].w;
	}
	dx=500;
	now=energy(dx);
	SA();
	cout<<fixed<<setprecision(4)<<energy(dx)<<endl;
}
int main()
{
	int t;
	cin>>t;
	while(t--) sjk();
	return 0;
} 

但是我们悲催的发现,只有吸氧可以过这个代码,不然只有 50 分。

怎么办!

打正解?No way!

温度?\(3000\) 就够!

降温速度?\(0.885\) 就行

ACcode(不吸氧):

#include <bits/stdc++.h>
using namespace std;
const double down=0.885;
int n;
struct node{
	int  x,y,w;
}a[10005];
double dx,now;
double energy(double x)
{
	double tot=-1e20;
	for(int i=1; i<=n; i++)
	{
		tot=max(tot,a[i].x*x*x+a[i].y*x+a[i].w);
	}
	return tot;
}
void SA()
{
	double t=3000;
	while(t>1e-17)
	{
		double tx=dx+(rand()*2-RAND_MAX)*t;
		if(tx<0) tx=0;
		if(tx>1000) tx=(1000);
		
      	double temp=energy(tx);
      	double delte=temp-now;
      	if(delte<0)
      	{
      		dx=tx;
      		now=temp;
		  }
		else if(exp(-delte/t)*RAND_MAX>rand())
		{
			dx=tx;
		}
		t*=down;
	}
}
void sjk()
{
	cin>>n;
	for(int i=1; i<=n; i++)
	{
		cin>>a[i].x>>a[i].y>>a[i].w;
	}
	dx=500;
	now=energy(dx);
	SA();
	cout<<fixed<<setprecision(4)<<energy(dx)<<endl;
}
int main()
{
	int t;
	cin>>t;
	while(t--) sjk();
	return 0;
} 

最后,让我们以一段有趣的笑话来结尾吧

一段 模拟退火

一台 电脑

一个夜晚

一个又 WA 又 TLE 的记录

管理员大大求通过 QAQ

posted @ 2026-02-24 17:29  Python_enjoy  阅读(2)  评论(0)    收藏  举报