题目:有n个人围成一个圈,将他们编号1~n,从第k个人开始报数,每次报到m的人退出,问:最后留下的那个人编号为多少?
公式:f[1] = 1; f[i] = (f[i - 1] + m) % i; if(f[i] == 0) f[i] = i; f[n] = f[n] + k - 1;
这是一个简单的约瑟夫环问题。我们先将问题简单化,假设是从第一个人开始报数的。
n个人中第一次报到m的人退出,这样,就剩下n - 1个人,这n - 1个人又组成了一个约瑟夫环问题,我们再给他们标上新的编号,那么,这n - 1个人中最后剩下的那个人必然是n个人中最后剩下的那个人。由此,我们可知,n - 1个人中最后剩下的人可由n - 2个人中最后剩下的那个人得到。
编号 1,2,3,……,n - 1,n ,共n个。从第一个人开始报数,设推出的编号为x,可知x = m % n;那么队列变成这样
1,2,3,……,x - 1,x + 1, ……,n - 1,n ,共n - 1个。我们将x + 1作为队首,x + 1前面的都补到n的后面,这样这个队列变为
x + 1,x + 2,……,n - 1,n,n + 1,……,n + x - 1,共n - 1个。这个队列里的编号%n即为上一个队列里的编号。
由此,我们知道了前一个约瑟夫环里的最后剩下的人通过编号的转换就可以知道多一个人的约瑟夫环问题的最后剩下的人的编号。
已知f[1] = 1;我们可以推出f[2],f[3],……,f[n]。最后这里的f[n]是从1开始报数的,要求从k开始报数的还得f[n] = f[n] + k - 1;