zoukankan      html  css  js  c++  java
  • 求圆圈中剩下的最后一个数字

    n个数字(0,1,…,n-1)形成一个圆圈,从数字0开始,每次从这个圆圈中删除第m个数字(第一个为当前数字本身,第二个为当前数字的下一个数字)。当一个数字删除后,从被删除数字的下一个继续删除第m个数字。求出在这个圆圈中剩下的最后一个数字。

    这个问题在wiki上叫约瑟夫斯问题。

    一开始的序列是

    S(n): n-1, 0, 1, 2, 3, ...., n -2 (一个环)

    删除了第k=(m-1)%n个数,之后变成

    S': n-1, 0, 1,2,...,k-1,k+1,...,n-2

    S(n-1): n-2, 0, 1,2,3, ...,n-3 

    将S(n-1)按照f(x)=(x+k+1)%n 进行映射可以得到S',也就是0->k+1, 1->k+2....

    将S'继续删除第k个数,以此类推,最后一个序列,也是可以通过S(1)来映射。

    S' = (S(n-1) + (m-1)%n + 1) % n = (S(n-1) + m) % n.

    那么对于每个序列的最后一个数, 也是满足这个映射。

    f(n) = (f(n-1) + m) % n.

    当n==1的时候,只有一个数,那么最后一个数肯定就是0,f(1) =0.

    然后就可用动态规划去做了。

    This approach has running time $O(n)$, but for small k and large n there is another approach. The second approach also uses dynamic programming but has running time $O(klog n)$. It is based on considering killing k-th, 2k-th, ..., $(lfloor n/k floor k)$-th people as one step, then changing the numbering.

    这里提到的第二种方法为什么会是$O(klog n)$,没想明白? 把杀掉k-th, 2k-th, ..., $(lfloor n/k floor k)$-th当个步骤,所以总共需要k步。那也就是说,重新编号的开销是$log n$.怎么做到的?

  • 相关阅读:
    2018软工实践之团队选题报告
    2018软工实践作业五之结对作业2
    2018软工实践作业四之团队展示
    2018软工实践作业四之团队展示
    2018软工实践作业三
    职场老鸟项目经理多年感悟
    项目冲突管理
    项目变更如何控制
    项目管理基础
    成功项目管理与PMP认证2017
  • 原文地址:https://www.cnblogs.com/linyx/p/3923617.html
Copyright © 2011-2022 走看看