• 约瑟夫问题


    问题提出:

    n个人(编号1~n)围成一个圈,从1开始依次报数,报到m的出列,剩下的人继续从1开始报数(由刚出列的人的下一个人开始)。求最后出列的人(胜利者)的编号。

    为了讨论方便,先把问题稍微改变一下,并不影响原意:

    问题描述:n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数。求胜利者的编号。
    我们知道第一个人(编号一定是m%n-1) 出列之后,剩下的n-1个人组成了一个新的约瑟夫环(以编号为k=m%n的人开始):
       k   k+1   k+2   ... n-2, n-1, 0, 1, 2, ... k-2,
    并且从k开始报0。
    现在我们把他们的编号做一下转换:
    k     --> 0
    k+1 --> 1
    k+2 --> 2
    ...
    k-2 --> n-2
    变换后就成为了(n-1)个人报数的子问题,假如这个子问题的解:x是胜利者,那么根据上表寻找x对应的值,这个值就是n个人时的解。变回去的公式:x'=(x+k)%n=(x+m)%n.
    如何知道(n-1)个人报数的问题的解?对,只要知道(n-2)个人的解就行了。(n-2)个人的解呢?当然是先求(n-3)的情况 ---- 这显然就是一个倒推问题。
    f[i]表示i个人玩游戏报m退出最后胜利者的编号,最后的结果自然是f[n]
    递推公式
    f[1]=0;
    f[i]=(f[i-1]+m)%i;   (i>1)
    有了这个公式,我们要做的就是从1至n顺序算出f[i]的数值,最后结果是f[n]。因为实际生活中编号总是从1开始,我们输出f[n]+1

    这个算法的时间复杂度为O(n)。

  • 相关阅读:
    hdu 4002 Find the maximum
    hdu 2837 坑题。
    hdu 3123
    zoj Treasure Hunt IV
    hdu 2053 Switch Game 水题一枚,鉴定完毕
    poj 1430 Binary Stirling Numbers
    hdu 3037 Saving Beans
    hdu 3944 dp?
    南阳oj 求N!的二进制表示最低位的1的位置(从右向左数)。
    fzu 2171 防守阵地 II
  • 原文地址:https://www.cnblogs.com/cszlg/p/2910506.html
Copyright © 2020-2023  润新知