约瑟夫环问题的公式推导

    题目:有n个人围成一个圈,将他们编号1~n,从第k个人开始报数,每次报到m的人退出,问:最后留下的那个人编号为多少?

    公式:f[1] = 1; f[i] = (f[i - 1] + m) % i; if(f[i] == 0) f[i] = i; f[n] = f[n] + k - 1;

    这是一个简单的约瑟夫环问题。我们先将问题简单化,假设是从第一个人开始报数的。

    n个人中第一次报到m的人退出,这样,就剩下n - 1个人,这n - 1个人又组成了一个约瑟夫环问题,我们再给他们标上新的编号,那么,这n - 1个人中最后剩下的那个人必然是n个人中最后剩下的那个人。由此,我们可知,n - 1个人中最后剩下的人可由n - 2个人中最后剩下的那个人得到。

    编号 1,2,3,……,n - 1,n ,共n个。从第一个人开始报数,设推出的编号为x,可知x = m % n;那么队列变成这样

            1,2,3,……,x - 1,x + 1, ……,n - 1,n ,共n - 1个。我们将x + 1作为队首,x + 1前面的都补到n的后面,这样这个队列变为

            x + 1,x + 2,……,n - 1,n,n + 1,……,n + x - 1,共n - 1个。这个队列里的编号%n即为上一个队列里的编号。

    由此,我们知道了前一个约瑟夫环里的最后剩下的人通过编号的转换就可以知道多一个人的约瑟夫环问题的最后剩下的人的编号。

    已知f[1] = 1;我们可以推出f[2],f[3],……,f[n]。最后这里的f[n]是从1开始报数的,要求从k开始报数的还得f[n] = f[n] + k - 1;

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值