https://www.luogu.com.cn/problem/P5544
这题模拟退火模板题,从求最小值变成了求最大值,题解都是把接受差解的概率去掉?我吐了
之后看看求最大值有没有什么接受差解的题解,代码先放博客上。。。
#include<bits/stdc++.h>
using namespace std;
const int maxl=1e3+10;
const int rndmx=100000;
const double eps=1e-15;
mt19937 rnd(time(0));
uniform_int_distribution<> dis(1,rndmx);
int n,m,ans;
double sx,sy,R,mxx,mxy,mix,miy;
struct node
{
double x,y,r;
}a[maxl],b[maxl];
inline void prework()
{
scanf("%d%d%lf",&n,&m,&R);
for(int i=1;i<=n;i++)
scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a[i].r);
sx=0;sy=0;
for(int i=1;i<=m;i++)
{
scanf("%lf%lf",&b[i].x,&b[i].y);
sx+=b[i].x;sy+=b[i].y;
}
sx/=m;sy/=m;mix=mxx=sx;miy=mxy=sy;
for(int i=1;i<=m;i++)
{
mix=min(b[i].x,mix),mxx=max(b[i].x,mxx);
miy=min(b[i].y,miy);mxy=max(b[i].y,mxy);
}
}
inline double dist(double x1,double y1,double x2,double y2)
{
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
inline int calc(double x,double y)
{
double r=R;
for(int i=1;i<=n;i++)
r=min(r,dist(x,y,a[i].x,a[i].y)-a[i].r);
if(r<eps) return 0;
int cnt=0;
for(int i=1;i<=m;i++)
if(dist(x,y,b[i].x,b[i].y)<r+eps)
++cnt;
return cnt;
}
inline void anneal()
{
double t=30000,x=sx,y=sy,nx,ny;
int now=calc(x,y),tmp,f;
ans=max(now,ans);
while(t>eps)
{
nx=x+(dis(rnd)*2-rndmx)*t;
//nx=((rand()<<1)-RAND_MAX)*t;
if(nx>mxx) nx=mxx;if(nx<mix) nx=mix;
ny=y+(dis(rnd)*2-rndmx)*t;
//ny=y+((rand()<<1)-RAND_MAX)*t;
if(ny>mxy) ny=mxy;if(ny<miy) ny=miy;
tmp=calc(nx,ny);
if(tmp>now)
{
now=tmp;ans=max(ans,tmp);
x=nx;y=ny;
}
else if(exp(-(now-tmp))/t>1.0*dis(rnd)/100000)
t*=0.9976;
}
}
inline void mainwork()
{
ans=0;
//while((double)clock()/CLOCKS_PER_SEC<=0.6)
anneal();
}
inline void print()
{
printf("%d",ans);
}
int main()
{
prework();
mainwork();
print();
return 0;
}