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$.怎么做到的?

  • 相关阅读:
    emWin模拟器Visual Studio开发时无法printf打印的问题
    双边滤波算法
    hough变换算法
    OpenCV3入门(十四)图像特效—挤压、哈哈镜、扭曲
    Canny检测算法与实现
    图像频域滤波与傅里叶变换
    OpenCV3入门(十二)角点检测
    OpenCV3入门(十一)图像直方图
    OpenCV3入门(十)图像轮廓
    一款基于SVM算法的分布式法律助手
  • 原文地址:https://www.cnblogs.com/linyx/p/3923617.html
Copyright © 2011-2022 走看看