1. 程式人生 > >約瑟夫環問題--遞迴推導

約瑟夫環問題--遞迴推導

本文為學習《劍指offer》的記錄。因其原理在原作者部落格上找不到,所以,只能自己編寫記錄,如有不當之處,歡迎指正。

題目描述:
n個數,編號為 0 , 1, ……, n-1 排成一個圓圈,從數字 0 開始,每次從這個圓圈中刪除第 m 個數,請問最後一個剩下的數是多少?

推導過程
定義一個函式 f(n, m) 為 n 個數中取 m 最後剩下的編號。
第一個被刪除的數是 (m-1)%n, 記為 k 。此時因為序列已經不連續,函式可以定義為 f’ ( n-1, m)
明顯,最後剩下的編號相等,於是: f(n,m) = f’(n-1, m)

然後我們對剩下的數做一個簡單的對映:

k+1 –> 0
k+2 –> 1
.
.
n-1 –> n-k-2
0 –> n-k-1
1 –> n-k
.
.
k-1 –> n-2

這個對映可以記為
p(x) = (x-k-1)%n
其中 x 為對映前的數 (可以自己推導一下)

那麼逆對映就是:
p-1(x) = (x + k + 1 ) %n
(還是建議自己推導一下)

那麼,對於上面的函式 f’(n-1, m),就有
f’(n-1, m) = p-1[f(n-1, m)] = [f(n-1, m) + k +1]%n = f(n, m)

k= (m-1)%n 代入:
f(n, m) = [f(n-1, m) + m]%n

這就是我們要的通項公式。
很明顯,當 n = 1 時,f = 0;
於是:

f(n, m) = 0, n = 1


f(n, m) = [f(n-1, m) + m]%n, n>1

使用迴圈就可以輕鬆解決這個問題了。

–END–