Contents
Problem
Josephus problem
(注意 城市 1 都會先被斷)
Solution
參考:https://en.wikipedia.org/wiki/Josephus_problem#The_general_case
直接用遞迴的公式去解即可。
這裡試著解釋看看,非嚴謹證明!有錯還煩請告知。
(直接用殺人代替斷網)
總共 n 人,如果從第 0 個人開始往後點第 k 個人,並殺掉他,會造成兩件事:
- 總人數減少 1 人
- 下一個起點變成是被殺掉的下一位,也就是下一次的起始位置往前移 $k\ mod\ n$
$f(n,k)$ 表示該狀況時,最後 剩下的人是誰。
初始狀態:$f(1,k) = 0$
當我們要求出 $f(n,k)$ 時先做第一件事,減少一人,而我們已經知道 $n-1$ 人時最後剩下的是 $f(n-1, k)$。
但 $f(n-1,k)$ 的起始點和現在不同,所以我們把結果做位移,也就是:
$f(n,k) = (f(n-1,k) + k)\ mod\ n$
關於起始不同,舉例來說 n = 5 (0, 1, 2, 3, 4), k = 3,第一個被殺的是 2。
下一狀態是 0, 1, 3, 4,且從 3 開始計算,也就是起點往前移了 $k\ mod\ n = 3$ 個。(0 -> 3)
可以試著列列看,如果保持 k 不變,僅移動起始點,殺人的順序會怎麼改變。
以 n = 5 來說起點為 0,順序為:
2 -> 0 -> 4 -> 1 -> (3)。
將起點改為 2,順序則變成:
0 -> 3 -> 2 -> 4 -> (1)。
可以發現接下來每個被殺的位置也都被往前移了 $k\ mod\ n = 3$。
回到題目的部分,先建好表,要注意 k 可能超過 n。
另外則是由於每次 城市 1 都會先被斷,我們直接把它排除,並將 index 從 0 開始計算。last[n - 1][k] == 0
時就是我們要找的 k 了。
Code
1 |
|