求解约瑟夫问题(Joseph Problem)的数学方法 from 御剑晨风

http://alexxyjiang.blog.163.com/blog/static/11713572120109210942883/

约瑟夫问题(Joseph Problem):

n个人(编号由0, 1, ..., n-1)围成一圈,由编号0的人从1开始报数,报到m的退出,剩下的人继续从1开始报数,直到圈内只剩余1人,求胜利者的编号。(n>0, m>0)

--------------------------------

求解约瑟夫问题,很容易想到的常规方法是模拟,不仅程序写起来比较烦,而且时间复杂度高达O(mn),当m,n非常大的时候,这样的时间复杂度就显得太高了。

有没有一种方法,能够降低计算的复杂度呢?答案是肯定的。

--------------------------------

我们可以通过数学推理得到这样的方法:

定义每一轮新的报数开始前后,以当前报数为1的人向正方向结合剩余的人构成的环为约瑟夫环。不失一般性,不妨设这是从(i+1)人到i人的过程(i>=0)

报数前后,分别对应着两个约瑟夫环:

报数前:0, 1, 2, 3, ..., i

报数后:0, 1, 2, 3, ..., (i-1)

这两个报数前后的环,显然是有关系的,是什么样的关系呢?

推理步骤如下:

1)在(i+1)报数到m的过程中,出列者的号码是(m-1)%(i+1),下一个报数人编号自然就是m%(i+1),不妨设为k;

2)建立报数前后的对应关系:

k    ---> 0

k+1  ---> 1

k+2  ---> 2

...

k-2  ---> i-1

(要注意:k-1号在前一轮出局)

3)设在i人中,最终剩余者的编号是x,那对于(i+1)人作逆推,容易得到(i+1)人中最终剩余者的编号x'满足如下关系:

x'=(x+k)%(i+1);

4)将(3)得到的公式作完整逆推,则可以得出最终的解;

用上述数学方法构建算法时间复杂度为O(n),不需要额外空间,空间复杂度为O(1)

--------------------------------

另外要说明的是,这个方法只能在o(n)的方法内求出第任意某个出去的人的位置。如果要求出整个出去序列,用这个方法还是o(n^2)的……求所以出去序列,用线段数可以做到o(nlog(n))..貌似没有比这个快的了……

转载于:https://www.cnblogs.com/Steven7Gao/archive/2011/10/17/2215936.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值