具体数学 - 底和顶的递归式 Floor and Ceiling Recurrence
我们将约瑟夫问题推广到一般情况,如果有 \(n\) 个人,每隔 \(q\) 个人就淘汰一个人,那么最后幸存者的号码是多少?
我们采用新的编号方式,第一个人不会被淘汰,则编号变为 \(n+1\);第二个人不会被淘汰,则编号变为 \(n+2\);直至第 \(q\) 个人被淘汰。第 \(q+1\) 个人重新编号为 \(n+q\),如此循环。假设已经淘汰了 \(k\)个人,则当前淘汰的人编号为 \(kq\),接下来的人编号为 \(n+k(q-1)+1\)。
以 \(n=10,q=3\) 为例,下面是编号更新的过程。
| iter/num | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | |||
| 2 | 18 | 19 | 20 | 21 | 22 | |||||
| 3 | 23 | 24 | 25 | |||||||
| 4 | 26 | 27 | ||||||||
| 5 | 28 | |||||||||
| 6 | 29 | |||||||||
| 7 | 30 |
到最后可以发现幸存者的编号为 \(qn\),如果我们能找出 \(qn\) 原来的编号,我们就能找出幸存者。从上述过程我们发现,编号为 \(kq+d\) 的人下一轮的编号为 \(n+k(q-1)+d\),其中 \(1 \leq d \leq q\)。令 \(N=n+k(q-1)+d\),则编号为 \(N\) 的人上一轮的编号为 \(kq+d=kq+N-n-k(q-1)=k+N-n\)。又因为 \(k=\frac{N-n-d}{q-1}=\lfloor \frac{N-n-1}{q-1} \rfloor\),则上一轮的编号可以表示为 \(\lfloor \frac{N-n-1}{q-1} \rfloor + N - n\)。使用 \(D=qn+1-N\) 代入原式,可以得到简明的递归式
\[\begin{align*}
D&= qn+1-N \\
&= qn+1-(\lfloor \frac{N-n-1}{q-1} \rfloor + N - n) \\
&= qn+1-(\lfloor \frac{(qn+1-D)-n-1}{q-1} \rfloor+(qn+1-D)-n) \\
&= n+D- \lfloor \frac{(q-1)n-D}{q-1} \rfloor \\
&= D- \lfloor -\frac{D}{q-1} \rfloor \\
&= D+ \lceil \frac{D}{q-1} \rceil \\
&= \lceil \frac{q}{q-1}D \rceil.
\end{align*}
\]
算法对应的伪代码如下
D = 1
while D <= (q-1)n:
D = ceil(Dq/(q-1))
res = qn + 1 - D

浙公网安备 33010602011771号