玄学算法,但是有必要知道一下以便日后骗分()
太幽默了。
洛谷
模拟退火
Simulated annealing - Wikipedia
模拟退火算法 - 百度百科
首先这个算法名字就很魔性,还要根据什么固体退火原理,听不懂(bu
其次我们发现这是一个叫做玄学的东西,它的精度会对它的结果和时间复杂度有所影响
思路
使用模拟退火,因为我觉得这就是模拟退火模板题。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| #include<bits/stdc++.h>
using namespace std;
struct node { int x,y,w; } a[10005]; int n;
double potential_energy(double nowx,double nowy) { double sum=0; for(int i=1;i<=n;i++) { double delx=nowx-a[i].x; double dely=nowy-a[i].y; sum+=(sqrt(delx*delx+dely*dely))*a[i].w; } return sum; }
double xans,yans; double ans=1e18+7,t; const double delta=0.993;
void simulate_anneal() { double xx=xans; double yy=yans; t=1926; while(t>1e-14) { double xtemp=xans+(rand()*2-RAND_MAX)*t; double ytemp=yans+(rand()*2-RAND_MAX)*t; double new_ans=potential_energy(xtemp,ytemp); double del=new_ans-ans; if(del<0) { xx=xtemp; yy=ytemp; xans=xx; yans=yy; ans=new_ans; } else if(exp(-del/t)*RAND_MAX>rand()) { xx=xtemp; yy=ytemp; } t*=delta; } }
int main() { cin>>n; for(int i=1;i<=n;i++) { cin>>a[i].x>>a[i].y>>a[i].w; } simulate_anneal(); simulate_anneal(); simulate_anneal(); printf("%.3lf %.3lf\n",xans,yans); return 0; }
|
关于二分
看到 JSOI2004]平衡点 / 吊打XXX - 洛谷专栏 (luogu.com.cn) 这个题解用的是二分,先放在这里吧,回头搞一下咩~