假设编号依次是 0,1,2,...,n-1 的n个人围成一个环,从编号是0的人开始依次报数,
从1报到m且报m的人从环里退出,后面的人重新从1开始报数,
直到剩下一个人为止,问环里最后剩下的那个人的编号是多少?
========================
显而易见:
n>1时才涉及到报数退出,n=1时最后那个人的编号就是0;
第一个退出的人的编号注定是 (m-1)%n;
========================
现在假设 n=10,m=3
0 1 2 3 4 5 6 7 8 9
第一个人出列后,环的序列为:
0 1 (*) 3 4 5 6 7 8 9
换个角度从编号3开始看这个环的序列,即:
3 4 5 6 7 8 9 0 1 (*)
我们可以使用规则((**)+m)%n = (*) 把该序列映射为(当然实际上是尝试映射的过程中找到的规则):
0 1 2 3 4 5 6 7 8 (**)
========================
令f[n]表示n个人玩游戏报m退出最后胜利者的编号,得到递推公式:
f[n]=0; (n=1)
f[n]=(f[n-1]+m)%n; (n>1)
有了这个公式,我们可以从1到n顺序计算出最后结果f[n]。
即,f[n-1]轮赢的不管是谁,其在f[n]里的标号都是(f[n-1]+m)%n,
又因为f[0]的标号就是最终的胜者,所以f[n]的标号就是最终的胜者