[JSOI2004]平衡點 / 吊打XXX
阿新 • • 發佈:2018-12-23
從自己的直觀感覺上,應該目標函式是一個單峰函式,因此不需要用到模擬退火的思想----以一定的概率接受更差解,只需爬山即可。這玩意兒太玄學了,大概是剛學,還不太理解這個過程吧。自己寫的爬山一會兒在bzoj可以過,洛谷過不了,修改了一些引數後又恰恰相反,而且還有精度低時洛谷可以過,把精度調高反而wa了,很是玄乎。
寫法一:
#include<bits/stdc++.h> using namespace std; int dx[]={1,0,-1,0},dy[]={0,1,0,-1}; int n,x[10005],y[10005],w[10005]; double T=200000,T_min=1e-4,delta=0.98; double nowx,nowy,now; double nextx,nexty,next; double calc(double px,double py) { double pos=0; for(int i=0;i<n;i++)pos+=w[i]*sqrt((px-x[i])*(px-x[i])+(py-y[i])*(py-y[i])); return pos; } int main() { //freopen("input.in","r",stdin); cin>>n; for(int i=0;i<n;i++)cin>>x[i]>>y[i]>>w[i]; now=calc(nowx,nowy); while(T>T_min) { int i=rand()%4; nextx=nowx+dx[i]*T; nexty=nowy+dy[i]*T; next=calc(nextx,nexty); if(next<now) { now=next; nowx=nextx; nowy=nexty; } T*=delta; } printf("%.3f %.3f\n",nowx,nowy); return 0; }
寫法二:
#include<bits/stdc++.h> using namespace std; #define LL long long int n,x[10005],y[10005],w[10005]; double T=192600,T_min=1e-14,delta=0.993; double nowx,nowy,now; double nextx,nexty,next; double calc(double px,double py) { double pos=0; for(int i=0;i<n;i++)pos+=w[i]*sqrt((px-x[i])*(px-x[i])+(py-y[i])*(py-y[i])); return pos; } int main() { srand(time(0)); // freopen("input.in","r",stdin); cin>>n; for(int i=0;i<n;i++)cin>>x[i]>>y[i]>>w[i]; now=calc(nowx,nowy); while(T>T_min) { double nextx=nowx+(rand()*2-RAND_MAX)*T; double nexty=nowy+(rand()*2-RAND_MAX)*T; next=calc(nextx,nexty); if(next<now) { now=next; nowx=nextx; nowy=nexty; } T*=delta; } printf("%.3f %.3f\n",nowx,nowy); return 0; }