約瑟夫環問題的理解

2022-07-07 20:24:11 字數 1322 閱讀 8158

據說著名猶太歷史學家josephus有過以下的故事:在羅馬人占領喬塔帕特後,39 個猶太人與josephus及他的朋友躲到乙個洞中,39個猶太人決定寧願死也不要被敵人抓到,於是決定了乙個自殺方式,41個人排成乙個圓圈,由第1個人開始報數,每報數到第3人該人就必須自殺,然後再由下乙個重新報數,直到所有人都自殺身亡為止。然而josephus 和他的朋友並不想遵從。首先從乙個人開始,越過k-2個人(因為第乙個人已經被越過),並殺掉第k個人。接著,再越過k-1個人,並殺掉第k個人。這個過程沿著圓圈一直進行,直到最終只剩下乙個人留下,這個人就可以繼續活著。問題是,給定了和,一開始要站在什麼地方才能避免被處決。josephus要他的朋友先假裝遵從,他將朋友與自己安排在第16個與第31個位置,於是逃過了這場死亡遊戲。

約瑟夫環一般描述:已知n個人(以編號1,2,3...n分別表示)圍坐在一張圓桌周圍。從編號為1的人開始報數,數到m的那個人出列;他的下乙個人又從1開始報數,數到m的那個人又出列;依此規律重複下去,直到圓桌周圍的人全部出列,求最後出列者的序號。

int fun(int n, int

m)

》可以這樣理解這個方法:

》當有n個人的時候,他們的編號依次是0、1、2、3、4、………、n-1。假設最後編號為x(n)的人會留下來。

》因為數到m的那個人會出列,那麼此輪中編號為(m-1)%n的人會出列,編號為(m+0)%n的人將做為下一輪編號為0的人,此輪編號為(m+i)%n的人將做為下一輪編號為i的人…

》因此當有n-1個人的時候,編號為i的人對應著上一輪編號為(m+i)%n的人。假設此輪編號為x(n-1)的人最終會留下來。因為編號為x(n-1)的人肯定對應著上一輪的x(n),所以有x(n)=(m+x(n-1))%n

》有了這個遞推公式,那我們就可以一直遞推到x(2)=(m+x(1))%2,而x(1)=0。

》所以我們可以這麼來寫這個函式:

》r = 0

》for i 從 2 到 n:

》r = (m+r)%i

》最終第r個人會留下來(如果從1開始編號就是第r+1個人最終會留下來)。

求解原始約瑟夫問題:就是尋求最後2人的序號,按上面描述,也就是x(2)有兩個序號0,1,其對應的x(n)的情況下序號為多少:

#include int fun0(int n,int

m)

return r+1;}

int fun1(int n,int

m)

return r+1;}

intmain()

驗證得知最後的結果為16,31,符合問題描述。

參考:

關於約瑟夫環問題的理解

有序列 0,1,2,3.n 1 可以將0 n 1的序列值理解為任意陣列下標 每次刪除第m個,注意該序列首尾相連,即n 1的下乙個為0,問最後剩下的數字是多少?此問題被稱為約瑟夫環問題,可以用列舉找規律解決,但也可以使用動態規劃來思考 1 記1 n 1序列最後剩下的數字為 f n,m 其中n表示有n個...

約瑟夫問題 約瑟夫環

約瑟夫 問題 有時也稱為約瑟夫斯置換,是乙個出現在電腦科學和數學中的問題。在計算機程式設計的演算法中,類似問題又稱為約瑟夫環。又稱 丟手絹問題 據說著名猶太歷史學家 josephus有過以下的故事 在羅馬人占領喬塔帕特後,39 個猶太人與josephus及他的朋友躲到乙個洞中,39個猶太人決定寧願死...

約瑟夫問題 約瑟夫環

約瑟夫問題 有時也稱為約瑟夫斯置換,是乙個出現在電腦科學和數學中的問題。在計算機程式設計的演算法中,類似問題又稱為約瑟夫環。又稱 丟手絹問題 據說著名猶太歷史學家 josephus有過以下的故事 在羅馬人占領喬塔帕特後,39 個猶太人與josephus及他的朋友躲到乙個洞中,39個猶太人決定寧願死也...