Jesephus problem ( 小议约瑟夫家的问题 )

本文探讨了猴子选大王问题的高效解决方法。通过递推公式f(i)=(f(i-1)+m)%i,实现了O(n)的时间复杂度。此外,还介绍了如何通过递推方法找出猴子出队序列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    问题描述:编号为1~n共n只猴子坐成一圈想要选大王,大家约定从1开始报数数到n的猴子退出,剩下的猴子继续从1开始报数,直到剩下最后一只猴子时,它就被选为大王。

    有一种常规的解决思路:模拟选大王的过程。用一个长度为n数组作为标志数组,将每次退出猴子对应编号上标记为FALSE,继续报数,遇到标记为false的元素跳过继续,直到数组中只剩一个标记为true的数组,其就是大王。时间复杂度O(mn)。

    为了感性认识,请大家考虑一种极端情况,如果n为100只,最后只剩下2只标记为true的猴子,我们为了得到大王,本只需在2只猴子间进行报数,谁最先报出m,则淘汰。但是程序的做法却需要将100个猴子扫描m-1次进行m-1计数,直到报出m。是不是很复杂?


    为了得到大王,我们得拿出我们数学这把利剑,采用递推方式,只需要时间复杂度为O(n)就能解决问题。下面细细道来

    递推方法:递推,顾名思义从猴子少的时候推到猴子多的时候,找其中的规律。因为习惯我们把编号设成0~n-1,对于上面问题求解时,我们再将编号加一就是了。以下取m=3进行说明。

   f(i):表示当猴子数量为i时,猴王的编号。例如:f(1)=0,当只有一只猴子时,其编号为0,它肯定就是猴王了。f(2)=1,两只猴子从编号为0开始报数,报数为3的猴子退出,很明显猴王编号为1。下面给出猴子依次变化时,猴王变化情况:

    

    发现规律了f(i)=(f(i-1)+m)%i.对这就是我们需要的。那么要求猴子总数为n的时候,已知初始值f(1)=0,又有了递推公式,是不是很简单了。


    再拓展下,我们能不能得到n只猴子依次出队的序列呢,如果这个知道,那儿我们就可以很容易算出编号为i的猴子是第几次出队的,是吧?

    咱们继续找规律吧。f(i)下面对应了一列数,从下往上,表示当猴子总数为i时,依次出队的先后顺序。

    

    

   是不是发现了?每个标蓝色的数字其对应的一行数字之间仍然是满足(f(j)+m)%i【采用(j)只是为了与猴王的f(i)避免冲突】,但是我们不知道递归的初始值啊,即:蓝色数字怎么求呢?有以下两个方案:

   1)对于f(i)序列中共有0,1··i-1个数,我们如果已经知道除了蓝色数以外的数字,通过搜索排除就能知道蓝色数

   2)针对每个f(i)序列和我们能算出,用其减去已递推了的数,就能知道蓝色数了

   时间复杂度为O(n*n).

   代码已传到优快云,希望大家多多批评指正。

       



    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值