玄学搜索\随稽化
正解又不會寫,又懶得去想
只好每次考試大大暴力,維持一下生活了
-----------------------
P1337 [JSOI2004]平衡點 / 吊打XXX
題目描述
有n個重物,每個重物系在一條足夠長的繩子上。每條繩子自上而下穿過桌面上的洞,然后系在一起。圖中X處就是公共的繩結(jié)。假設(shè)繩子是完全彈性的(不會造成能量損失),桌子足夠高(因而重物不會垂到地上),且忽略所有的摩擦。
問繩結(jié)X最終平衡于何處。
注意:桌面上的洞都比繩結(jié)X小得多,所以即使某個重物特別重,繩結(jié)X也不可能穿過桌面上的洞掉下來,最多是卡在某個洞口處。
這道題,是一道模你模擬退火的板子題
我是看這個大佬看懂的
我一開始看這個算法,是拒絕的。你不能叫我玄學(xué)就玄學(xué)。
然鵝這是玄學(xué)的特技,是特技的玄學(xué)。對于搜索偏分還是很好用的
提醒:公式不要死磕
exp是計算自然對數(shù)次方的函數(shù)
參數(shù)是個玄學(xué)的東西,要不斷地摸索和聯(lián)系
解不一定是最優(yōu),但時間復(fù)雜度低
算法大概:
從當(dāng)前狀態(tài)通過一個不斷縮減的步長轉(zhuǎn)移到下一個狀態(tài)
然后計算待轉(zhuǎn)移狀態(tài)的優(yōu)劣程度,這個優(yōu)劣程度就是能量
然后比當(dāng)前狀態(tài)優(yōu)的話,就貪心的進行轉(zhuǎn)移
不優(yōu)的話,就根據(jù)那個鬼的公式。算概率轉(zhuǎn)移
假ac代碼:
#include<cstdio> #include<iostream> #include<algorithm> #include<cstdlib> #include<ctime> #include<cmath> const int maxn=10100; const double eps=1e-14; struct node {int x,y;int w; }; node pos[maxn]; int n; double anx,any; double calc(double x,double y) {double res=0;for(int i=1;i<=n;i++){double px=x-pos[i].x;double py=y-pos[i].y;res+=sqrt(px*px+py*py)*pos[i].w;}return res; } void simulate() {double t=250;while(t>eps){double nowx=anx+((rand()<<1)-RAND_MAX)*t;double nowy=any+((rand()<<1)-RAND_MAX)*t;double delta_E=calc(nowx,nowy)-calc(anx,any);if(delta_E<0)anx=nowx,any=nowy;else if(exp(-delta_E/t)*RAND_MAX>rand())anx=nowx,any=nowy;t=t*0.997;} } int main() {srand(臉);scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d%d%d",&pos[i].x,&pos[i].y,&pos[i].w);anx+=pos[i].x;any+=pos[i].y;}anx=1.0*anx/n;any=1.0*any/n;simulate();printf("%.3lf %.3lf",anx,any); }模擬退火對于我這種noip狗肯定是不會考
但是多一個偏分的技巧不是很好嗎
隨機化
隨機化運用在搜索中,枚舉中。在運行次數(shù)足夠多的情況下,可以有效避免貪心的錯誤,即使使用了貪心
07年noip的寶藏。
就可以使用這種方法騙分。
運行一次prim的時間很短,我們可以多次運行
我們在使用優(yōu)先隊列選邊時,可以rand出一個概率來
然后再根據(jù)概率加進我們的生成樹中去
轉(zhuǎn)載于:https://www.cnblogs.com/Lance1ot/p/9495457.html
總結(jié)
- 上一篇: 12C RAC for ASM添加磁盘步
- 下一篇: 2018企业面试总汇(答案请自行搜罗)