圆圈报数-约瑟夫问题

本文介绍了约瑟夫问题,即n个人围圈报数,数到m的人出圈。从初始级算法到优化算法再到动态规划算法进行深入探讨,详细解释了动态规划算法的思路和公式,实现代码展示了解决问题的过程。强调动态规划在解决递归问题中的高效性。
摘要由CSDN通过智能技术生成

问题概述

约瑟夫问题:n个人围成一圈,从第一个人开始报数,数到m的人出圈;再由下一个人开始报数,数到m的人出圈;…输出依次出圈的人的编号。n,m由键盘输入。

解题思路

1 初始级算法
循环报数,每次数到m的倍数就出局此时指向的人。
可以通过list或者是指针来实现保存当前还在游戏中的人的功能,通过索引去出局人。
但是这样的算法效率很低,基本上要O(m*n)的时间复杂度。

2优化算法
不需要通过循环报数,循环中很多步骤都是浪费的,如果当前游戏中还有n1个人,
如果给这个n1个人编号 从1到n1
那么下一次出局的人会是编号 (m+n1-1)%n1+1 或者简化为(m-1)%n1+1
通过这样的优化可以快速找到每一轮需要出局的人,这种情况下如list来存储当前还在游戏中的人的功能就会存在一定的优势。最后时间复杂度为O(n)

3动态规划算法
反思之前为什么要用额外的空间保存当前还在游戏中的人,那就是因为每一轮游戏结束之后部分人的索引改变了,如下
如果当前游戏还有n个人,从1到n进行编号,并且这一轮编号为a 的人出局了
原始: 1 2 3 … a-1 a a+1 …n
a出局之后: 1 2 3 … a-1 a+1 …n
编号a-1的人的下一位人的从n变为了n+1

而报数顺序变成了如下结构
a+1 a+2 …n 1 2 3 …a-1

如果我们按照这样的报数顺序对人重新编号,得到一个从1到n-1的数列,这个步骤相当于对原来人的编号进

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值