【問題描述】
有 n(n<=20)臺 pc 放在機房內,現在要求由你選定一台 pc,用共n−1條網線從這台機器開始一台接一台地依次連線他們,最後接到哪個以及連線的順序也是由你選定的,為了節省材料,網線都拉直。求最少需要一次性購買多長的網線。(說白了,就是找出 n 的乙個排列 p1p2p3..pn 然後 p1−>p2−>p3−>…−>pn 找出 |p1p2|+|p2p3|+…+|pn−1pn| 長度的最小值)
【輸入格式】
第一行 n ,下面 n 行,每行分別為機器的座標(x,y)(x為實數−100<=x,y<=100)
【輸出格式】
最小的長度,保留兩位小數。
【輸入樣例】
3 0 0
1 1
1 -1
【輸出樣例】
2.83
這題似乎可以用數字dp來做,但對於那是什麼都不知道的本蒟蒻來說,隨機化貪心才是解這種哈密頓環的最佳方法。(而且一點都不慢。。。)還有對於哈密頓環的路徑優化不太熟的同學,可以試試自己畫圖,很容易就懂了,勤動腦的同時也要勤動手。
舉個例子,i,j分別表示一條路徑上的兩個點,i-1和j+1是它們前後的兩個點,n[i][j]表示i與j之間的距離,如果n[i-1][i]+n[j][j+1]>n[i-1][j]+n[i][j+1],也就是說i-1與i相連,j與j+1相連的距離是大於i-1與j相連,i與j+1相連的,那麼我們就更改路徑,讓i-1與j相連,i與j+1相連,那麼總路程就會變短。如果有n個點,讓i從1到n-1遍歷,j從i+1到n遍歷,優化之後就是在不改變點的位置,只改變路徑(當然陣列dis裡存的點會改變,但那只是為了計算路徑,使前後兩個點是直接相連的)情況下的最短距離,多隨機幾次即可矇到正解。。。
#include
#include
#include
int k,dis[25];
double n[25][25],x[25],y[25],sum,min;
void swap(int *a,int *b)
void sv(int a,int b)
double solve()
for(i=1;ifor(j=i+1;j<=k;j++)
if(n[dis[i-1]][dis[i]]+n[dis[j]][dis[j+1]]>n[dis[i-1]][dis[j]]+n[dis[i]][dis[j+1]])
sv(i,j);
for(i=1;i1]];
return t;
}int main()
for(i=1;i<=k;i++)
dis[i]=i;
sum=199999999;
for(i=1;i<=2000;i++)
隨機化演算法
隨機化演算法的主要目的是希望讓隨機發生在演算法上,而不是發生在輸入分布上,這樣的話,沒有特別的輸入會引起我們的演算法的最壞情況。即使你最壞的敵人也無法產生最壞的輸入陣列。因為隨機排列使得輸入次序不再相關。只有在隨機數生成器產生乙個不走運的排列時,隨機演算法才會執行得很差。一.隨機優先順序陣列法 我們...
隨機化搜尋
參與考古挖掘的小明得到了乙份藏寶圖,藏寶圖上標出了 nn 個深埋在地下的寶藏屋,也給出了這 nn 個寶藏屋之間可供開發的mm 條道路和它們的長度。小明決心親自前往挖掘所有寶藏屋中的寶藏。但是,每個寶藏屋距離地面都很遠,也就是說,從地面打通一條到某個寶藏屋的道路是很困難的,而開發寶藏屋之間的道路 則相...
簡單隨機化
有乙個挺不錯的 隨機化blog codechef mstones 平面上有 n 個點 x i,y i 保證這 n 個點可以用 7 條直線覆蓋。找出一條直線使得它覆蓋的點最多 30 組 test n leq10 4 x i y i leq1.5 times10 4 每次隨機找兩個點 a,b 判斷它們所...