約瑟夫問題 公式原理詳解

2021-10-05 00:23:20 字數 2241 閱讀 3519

在計算機程式設計的演算法中,類似問題又稱為約瑟夫環

約瑟夫環:n個人圍成一圈,從第乙個開始報數,第m個將被殺掉,最後剩下乙個,其餘人都將被殺掉。

例如n=6,m=5,被殺掉的順序是:5,4,6,2,3,1。

如圖:

如果我們從n個人開始乙個乙個的將被殺死的取出,我們要不斷的迴圈遍歷約瑟夫環,時間複雜度高達o(m*n)

假設我們反向推導,從只有乙個人參與這個遊戲開始,遞推出n個人參加遊戲的結果,就會變得簡單多了,推導原理如下:

總人數:1人

f(1,5)=

0,假設存活人的序號為x

總人數:2人:

假設另外乙個被殺的人的序號是a,則報數順序是一定的

報數順序:a x a x a (一死一活,已知x號是存活者,則第五個報數人必死)

假設我們每次都是從位置0處開始報數的,則可知排序位置:序號[位置]

排序位置:a[

0] x[1]

;總人數:3人

假設第二位被殺的人的序號是b,則報數順序依然確定

報數順序:x b a x b(倆個條件確定順序:1、第五個一定是b死;2、b死後總人數為2的排序已知)

排序位置:x[

0] b[

1] a[2]

總人數:4人

假設第三位被殺的人的序號是c,則報數順序依然確定

報數順序:c x b a c(同理)

排序位置:c[

0] x[

1] b[

2] a[3]

總人數:5人

假設第四位被殺的人的序號是d,則報數順序依然確定

報數順序:c a b 1 d(同理)

排序位置:c[

0] x[

1] b[

2] a[

3] d[4]

總人數:6人

假設第五位被殺的人的序號是e,則報數順序依然確定

報數順序:c a b 1 e(e插入1和d之間)

排序位置:x[

0] b[

1] a[

2] d[

3] e[

4] c[5]

最後推導出存活者的位置,從而得出存活者序號=當前位置+

1

如圖:

假設:

存活者位置 = f(n,m);

例如n=6,m=5,被殺掉的順序是:5,4,6,2,3,1。可知:

存活者位置 = f(6,5);

給出例子中求存活者位置的遞推過程

f(1,5)= 0

f(2,5)= (f(1,5)+5)% 2 = 1

f(3,5)= (f(2,5)+5)% 3 = 0

f(4,5)= (f(3,5)+5)% 4 = 1

f(5,5)= (f(4,5)+5)% 5 = 1

f(6,5)= (f(5,5)+5)% 6 = 0

思考:為什麼加5取餘?

例:f(3,5)= (f(2,5)+5)% 3 = 0

第一:加五是因為每報五個數就殺一人

第二:取餘是因為只有3個人的位置

1、因為在兩個人的基礎上多了乙個人,而這個多出來的乙個人一定是報第五個數而被殺的人,所以存活者的位置增加了五個位置單位,

2、此時總共才三個人,也就只有0、1、2三個位置,而要增加五個單位,例如三個人的位置分別為[0] 、[1]、[2],增加五個位置單位,[1]->[2]->[0]->[1]->[2]->[0],也就是環形遍歷約瑟夫環,得出最後停在[0]的位置,這也是取3的餘數得出的結果。

最後我們得出公式

f(n,m)=(f(n-1,m)+m)%n

#include

intmain()

return0;

}

約瑟夫環問題(遞推公式)

約瑟夫環問題在 具體數學 一書上講得十分詳細 基本問題描述 已知n個人 以編號1,2,3 n分別表示 圍坐在一張圓桌周圍。從編號為1的人開始報數,數到m的那個人出列 他的下乙個人又從1開始報數,數到m的那個人又出列 依此規律重複下去,直到圓桌周圍的人全部出列。也類似於 殺人狂問題 通常解決這類問題時...

約瑟夫問題詳解

name 約瑟夫環 模擬 author 李帥 date 10 11 08 23 53 description 約瑟夫問題 一群人圍成一圈,這群人共有 n個人,每個人身上都乙個value,依次給這圈人編號 1,2,n 一開始報數的上限值為m從第乙個人 編號 1 自一開始報數報到m時停止報數,報到m的人...

約瑟夫問題詳解

約瑟夫問題記得是在學習c語言陣列的時候寫過的一道題目,至於什麼是約瑟夫問題我想大多數學過c的人都應該知道的,下面就來說下如何利用陣列解決約瑟夫問題。預設的約瑟夫問題是從第乙個人開始計數,並且留下最後乙個倖存者,筆者做的改進是可以從指定位置起始計數,並且可以留下指定的人數,並且可以檢視被踢出的人。最開...