约瑟夫环的递推方法

可以这样理解这个方法:
当有n个人的时候,他们的编号依次是0、1、2、3、4、………、n-1。假设最后编号为x(n)的人会留下来。
因为数到m的那个人会出列,那么此轮中编号为(m-1)%n的人会出列,编号为(m+0)%n的人将做为下一轮编号为0的人,此轮编号为(m+i)%n的人将做为下一轮编号为i的人…
因此当有n-1个人的时候,编号为i的人对应着上一轮编号为(m+i)%n的人。假设此轮编号为x(n-1)的人最终会留下来。因为编号为x(n-1)的人肯定对应着上一轮的x(n),所以有x(n)=(m+x(n-1))%n
有了这个递推公式,那我们就可以一直递推到x(2)=(m+x(1))%2,而x(1)=0。
所以我们可以这么来写这个函数:
j = 0

for i 从 2 到 n:

j = (m+j)%i

最终第j个人会留下来(如果从1开始编号就是第j+1个人最终会留下来)。

链接:https://www.zhihu.com/question/20065611/answer/78681758
来源:知乎

时间: 2024-10-29 00:40:05

约瑟夫环的递推方法的相关文章

约瑟夫环-公式递推法

约瑟夫问题 约瑟夫问题是个著名的问题:N个人围成一圈,第一个人从1开始报数,报M的将被杀掉,下一个人接着从1开始报.如此反复,最后剩下一个,求最后的胜利者. 例如只有三个人,把他们叫做A.B.C,他们围成一圈,从A开始报数,假设报2的人被杀掉. 首先A开始报数,他报1.侥幸逃过一劫. 然后轮到B报数,他报2.非常惨,他被杀了 C接着从1开始报数 接着轮到A报数,他报2.也被杀死了. 最终胜利者是C 解决方案 普通解法 刚学数据结构的时候,我们可能用链表的方法去模拟这个过程,N个人看作是N个链表节

约瑟夫环问题--递推解法

利用数学推导,如果能得出一个通式,就可以利用递归.循环等手段解决.下面给出推导的过程: (1)第一个被删除的数为 (m - 1) % n. (2)假设第二轮的开始数字为k,那么这n - 1个数构成的约瑟夫环为k, k + 1, k + 2, k +3, .....,k - 3, k - 2.做一个简单的映射. k         ----->  0              k+1    ------> 1              k+2    ------> 2           

1025 数的划分(搜索和递推方法)

难度:普及/提高- 题目类型:递推 提交次数:3 涉及知识:动规 题目描述 将整数n分成k份,且每份不能为空,任意两个方案不相同(不考虑顺序). 例如:n=7,k=3,下面三种分法被认为是相同的. 1,1,5; 1,5,1; 5,1,1; 问有多少种不同的分法. 输入输出格式 输入格式: n,k (6<n<=200,2<=k<=6) 输出格式: 一个整数,即不同的分法. 搜索: 代码: 1 #include<iostream> 2 using namespace std

解决约瑟夫环的三种方法

假设有一圈石子,从1到n比较.然后依次每隔一个石子选出一个,直到剩余一个:问最后选出的石子的编号是多少: (至少)有三种方法可以解决这个问题:如下面的代码所示: object App extends App {   def native(n: Int): Int = {     def dispatch(pre: List[Int], list: List[Int]): List[Int] =       list match {         case Nil => pre         

约瑟夫环之递归实现

网上的递推方法实在是看不懂,只能用土办法-归纳总结.经过推算,假如不是从0开始会很麻烦.在归纳的时候发现有问题可以灵活一点. 个数               数据                   最后一个退出的编号  1                  0                            0                                   0  2               0    1                         1  

【DP】一道递推题。。。

Bob想要构造一张由n个节点构成的图.构造的过程由两步组成:首先Bob会取出n个孤立的点,并把它们从1到n编号,然后对每个节点用一种颜色染色,Bob一共可以使用K种不同的颜色.接下来Bob会在这张图中加入一些有向边,对于每一个编号范围在[2,n]的节点i,Bob有可能选择一个节点j满足j < i并且节点i与j的颜色不同,然后加入一条从i到j的有向边,对于节点i,Bob也有可能不加任何的有向边.现在你需要回答Bob有可能构造出多少种不同的图. 输入: 第一行包含三个整数n,K. 输出: 输出一个整

分别使用结构体和数组实现约瑟夫环(围圈报数问题之二)

前天用单循环链表实现了约瑟夫环问题,这种方法执行效率高.接下来用另外两种简单的方法实现之. 方法一:使用数组 void main() { int a[81],n,i,counter,num; //counter用来计算,num用来记录退出的人数 printf("please input total the number of person:"); scanf("%d",&n); for(i=0;i<n;i++) //为每个人编号,1~n { a[i]=

动态规划 数字三角形(递归,递推,记忆化搜索)

题目要求: 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 在上面的数字三角形中寻找在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大.路径上的每一步都只能往左下或右下走.只需要求出这个最大和即可,不必给出具体路径. 三角形的行数大于1小于等于100,数字为 0 - 99 输入格式: 5 //三角形行数.下面是三角形 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 解题思路: 用二维数组存放数字三角形 D[r][j] //表示第i行第j个元素的

(递推)一只小蜜蜂... hdu2044

一只小蜜蜂... 链接:http://acm.hdu.edu.cn/showproblem.php?pid=2044 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 95054    Accepted Submission(s): 33882 Problem Description 有一只经过训练的蜜蜂只能爬向右侧相邻的蜂房,不能反向爬行