约瑟夫环问题:递推公式(个人推导详解)

 题目: 有N个人围成1圈,数到第M个人时退出,剩下的继续,直到剩下最后1个人!求这个人是在原来N个人中的第几个?

例如:有5个人 ,数到3的人退出,即N=5    M=3

每轮只去掉1个人。

第一轮从1开始数,即 1 2 3 4 5   ,3退出   这是下一轮从 4开始数 即 4 5 1 2   

中间过程:
                M%N可以求出退出的人即  3%5=3   下一轮开始数字为 3+1  那么这个4在原来N中的位置即 (1+M)%N  
   为什么是(1+M)%N ? 而不是  M%N+1 呢?(一) 暂时保留疑问继续下一步

第二轮: 4 5 1 2         ,根据原来的公式   M%N=退出的人数为  第三个 即 3%4=3   下一轮从 第四个开始
中间过程:
第四个在原来第一轮的位置又是什么?
            我们知道第二轮中第一数为  第一轮中的第四个数,那么我们第二轮中的第四个数,应该是第一轮中的第7个数
        但原来只有5个数 没有第7个数字?这是有重复第7个数就为   7%5=2第一轮中的第二个数 
        这时第二轮可以写成
: ( M%N +1)  ,(M%N+2),(M%N+3),(M%N+4)
:    3%5+1=4,     3%5+2=5,  3%5+3=6  ,3%5+4=7
: 4, 5, 6 ,7
:6和7 实际又为 1和 2   
6与7怎么转换为1 和2 的呢? 

为什么是(1+M)%N ? 而不是  M%N+1 呢?(一) 暂时保留疑问继续下一步

1,2,3,4,5,1,2     我们数到5 之后在数又从1开始  这和取模刚好一致  6%5余1即又从1开始7%5余2,这是就是2。。。。所以我们用   (1+M)%N  这种方式  而不是 M%N+1  

那么第二轮继续转换为:
(1+M) %N  ,  (2+M) %N  ,  (3+M) %N , (4+M) %N,
即:4,5(0)(因为N等于5从1开始第5个即5%5=0,0代表最后1个),1,2
    4,5,1,2

第二轮:这时可以将问题看成  有N-1个人,数到M个人退出的新问题。。。
即和原来的问题一致那么同样的解法,我们知道下一轮第一个元素也是,(1+M)%N   。。。。。
……

最后一轮:这时只有1个数字,求N=1 数到第M个人退出的新问题!,我知道最后一定是第一人胜出,因为只有1个人,不用在退出,这时已经胜出了。。。。那么上一轮,有2个人,1,2 我们要找出最后一轮胜出的人在倒数第二轮的位置即可,,,这个第1个人可以看成N-1人问题中胜出人的位置X。。。现在X=1;

我们知道了下一轮的第一个元素位置就是 ,(1+M)%N 这时m还是等于3 求出n的位置。。。  但这是N只有2个人哦。N中的第(3+1)%2 = 0    =》   即第2个位置  将第N-1次胜出的1换成X即
 (X+M)%N= 0  =>2   那么现在我们知道了 倒数第二轮胜出的人为 位置为 2 的人。。。我们可以将他看成一个新的X=2;
我们知道了倒数第二轮胜出的人,那么同理我们可以求出倒数第三轮胜出的人的位置为,(X+M)%N   这就推出了
求: F(n)=(F(n-1)+M)%n     的位置只要知道F(n-1)胜出的即可,直到最后剩下1个元素为第1。
          F(n-1)=(F(n-2)+M)%(n-1)
          ……
          F(2)=(F(1)+M)%(n-n+2)           
          F(1)=1;

胜出人的位置为 :
     最后胜出的为:s=1;
        M=3;
        n=5;
       从倒数第二轮开始所以i=2;
        for(i=2;i<=n;i++){
            s=(s+M)%i;
                if(s==0){
                    s=i;
                }
        }

但是这样还有个问题。(x+M)%  因为如  2个人时,第二个人胜出 (1+3)%2=0   我们知道胜出的人为第二个,但结果是0,我们没有第0个位置,第0个就是最后1个位置,也就是2,这时我们数字中多了1个数字(0和i 是同一个), 但计算机只认为是0我们就要加个判断,if(s==0)  s=i .但这样还不是最优的解决方式。。。
我们将问题修改一下,改为
1,2,3,4,5        0,1,2,3,4
4,5,1,2              0,1,2,3
2,4,5                    0,1,2
2,4                          0,1
4                                0

我们将位置往左移1个位置,这样原来0就变成了N ,因为是个圆环,
还是原来的例子,如2个人时,第一个人胜出即  (0+3)%2=1 ,我们将0变为第一个,1即原来的第二个.这样就消除了0和i重复的问题了。。。因为0已经有意义就是第一个元素,原来的0是没有意义的,但我们设计时知道是个圆环,0就是第一个数字前的1个也就是最后1个数字。这样0和最后1个数字就冲突了。我们从0开始,这样就不存在冲突问题。。。。。。
所以式子最后为。。。
n=人数
M=要退出的数字
s=0;最后剩下的1个人的位置。0,代表第一个,因为最后只剩下1个人
for(i=2;i<=n;i++){
    s=(s+M)%i;
}
位置为:第s+1个数字(0即第一个)


转载于:https://my.oschina.net/dichanger/blog/528219

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值