约瑟夫斯问题(有时也称为约瑟夫斯置换),是一个出现在计算机科学和数学中的问题。在计算机编程的算法中,类似问题又称为约瑟夫环

有n个囚犯站成一个圆圈,准备处决。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。

接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。

问题是,给定了n和k,一开始要站在什么地方才能避免被处决?

问题是以弗拉维奥·约瑟夫斯命名的,它是1世纪的一名犹太历史学家。他在自己的日记中写道,他和他的40个战友被罗马军队包围在洞中。他们讨论是自杀还是被俘,最终决定自杀,并以抽签的方式决定谁杀掉谁。约瑟夫斯和另外一个人是最后两个留下的人。约瑟夫斯说服了那个人,他们将向罗马军队投降,不再自杀。约瑟夫斯把他的存活归因于运气或天意,他不知道是哪一个。

解法

1.用循环单链表模拟整个过程,时间复杂度是O(n*m)

2.如果只是想求得最后剩下的人,则可以用数学推导的方式得出公式。

要模拟整个游戏过程,不仅程序写起来比较烦,而且时间复杂度高达O(nm),当n,m非常大(例如上百万,上千万)的时候,几乎是没有办法在短时间内出结果的。我们注意到原问题仅仅是要求出最后的胜利者的序号,而不是要读者模拟整个过程。因此如果要追求效率,就要打破常规,实施一点数学策略。

为了讨论方便,先把问题稍微改变一下,并不影响原意:
问题描述:n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数。求胜利者的编号。

我们知道第一个人(编号一定是m%n-1) 出列之后,剩下的n-1个人组成了一个新的约瑟夫环(以编号为k=m%n的人开始):
  k  k+1  k+2  ... n-2, n-1, 0, 1, 2, ... k-2并且从k开始报0。
现在我们把他们的编号做一下转换:

k     --> 0
k+1   --> 1
k+2   --> 2
...
...
k-2   --> n-2
k-1   --> n-1
变换后就完完全全成为了(n-1)个人报数的子问题,假如我们知道这个子问题的解:例如x是最终的胜利者,那么根据上面这个表把这个x变回去不刚好就是n个人情况的解吗?!!变回去的公式很简单,相信大家都可以推出来:x'=(x+k)%n

如何知道(n-1)个人报数的问题的解?对,只要知道(n-2)个人的解就行了。(n-2)个人的解呢?当然是先求(n-3)的情况 ---- 这显然就是一个倒推问题!好了,思路出来了,下面写递推公式:

令f[i]表示i个人玩游戏报m退出最后胜利者的编号,最后的结果自然是f[n]

递推公式
f[1]=0;
f[i]=(f[i-1]+m)%i;  (i>1)

有了这个公式,我们要做的就是从1-n顺序算出f[i]的数值,最后结果是f[n]。因为实际生活中编号总是从1开始,我们输出f[n]+1
由于是逐级递推,不需要保存每个f[i],程序也是异常简单:

#include <stdio.h>
int main()
{int n, m, i, s = 0;printf ("N M = ");scanf("%d%d", &n, &m);for (i = 2; i <= n; i++){s = (s + m) % i;}printf ("\nThe winner is %d\n", s+1);
}

这个算法的时间复杂度为O(n),相对于模拟算法已经有了很大的提高。算n,m等于一百万,一千万的情况不是问题了。可见,适当地运用数学策略,不仅可以让编程变得简单,而且往往会成倍地提高算法执行效率。

相比之下,解法二的优越性不言而喻,同时说明数学确实很重要。

  • 组合数学
  • 置换
  • 计算机科学基础理论
  • 数学问题

http://blog.csdn.net/wuzhekai1985/article/details/6628491

http://www.cnblogs.com/EricYang/archive/2009/09/04/1560478.html

转载于:https://www.cnblogs.com/kimsimple/p/7468330.html

组合数学--约瑟夫环问题 Josephus相关推荐

  1. PTA 线性表 7-1 约瑟夫环(Josephus)问题(by Yan) (100分) 按出列次序输出每个人的编号

    7-1 约瑟夫环(Josephus)问题(by Yan) (100分) 编号为1,2,-,n的n个人按顺时针方向围坐在一张圆桌周围,每人持有一个密码(正整数).一开始任选一个正整数m作为报数上限值,从 ...

  2. 约瑟夫环(Josephus Circle)

    目录 一.问题描述 二.用数组求解 三.用递归求解 一.问题描述 约瑟夫环(Josephus Circle)是一个数学的应用问题:已知 n 个人(分别用编号 0, 1, 2, ..., n - 1 表 ...

  3. 求约瑟夫环问题最后胜利者的一般解法以及数学推导方法

    问题描述: 约瑟夫环问题(Josephus) 用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出.写出C程序. 解法一: 思路:建立一个有N个元素的循环链表,然后从链表表头遍 ...

  4. 动态规划解决约瑟夫环问题

    题目: 约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号0,1,2,3-n-1分别表示)围坐在一张圆桌周围.从编号为0的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m ...

  5. 【数据结构与算法】 01 链表 (单链表、双向链表、循环链表、块状链表、头结点、链表反转与排序、约瑟夫环问题)

    一.线性表 1.1 概念与特点 1.2 线性表的存储结构 1.3 常见操作 1.4 应用场景 二.链表 2.1 链表简介 2.2 单向链表(单链表) 2.21 基本概念 2.22 单链表基本操作 2. ...

  6. 约瑟夫环问题(数学方法)

    问题描述: 约瑟夫环问题(Josephus) 用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出.写出C程序. 解法一: 思路:建立一个有N个元素的循环链表,然后从链表表头遍 ...

  7. 约瑟夫环问题(Josephus)

    问题描述:设有编号 1,2,···,n 的 n(n>0)个人围成一个圈,从某个人开始报数,报到 m 时停止报数,报 m 的人出圈,再从他的下一个人起重新报数,报到 m 时停止报数,报 m 的出圈 ...

  8. Java实现Josephus约瑟夫环问题的算法

    Java实现Josephus约瑟夫环问题的算法 前言 语言:Java 环境:IntelliJ IDEA JDK版本:1.8 源码:GitHub 问题概述 N个人围成一圈,规定报数为M,第一个人从1开始 ...

  9. 深度剖析Josephus ring(约瑟夫环)C语言版

    深度剖析Josephus ring(约瑟夫环)C语言版 鉴于C语言更适合展示算法的底层设计,并且便于读者的研究与思考,故而小编使用C语言来展示约瑟夫环的精巧与奥妙. Hello!!各位同学们,欢迎来到 ...

最新文章

  1. ubuntu安装Java开发环境
  2. qpython3使用手册图_qpython图形
  3. NIFI使用过程中的invalid component问题解决
  4. jq cookie的使用
  5. 为什么黑客都用python-为什么如此多的黑客都用python?
  6. thinkPHP5项目上传到centOS服务器后不显示验证码图片
  7. FISCO BCOS(三)——— 部署及调用HelloWorld合约
  8. java 链表实现堆栈_用JAVA实现堆栈(链表篇)
  9. SHOPEX网店系统测试,50万家网站的安全令人担忧
  10. GH4169高温合金执行什么标准
  11. GPS从入门到放弃(十七) --- 对流层延时
  12. 方便地边看便翻译原版pdf文章(wps)
  13. 圆角装饰条_护角条是圆角好还是直角好
  14. 7.STM32F407ZG串口通信配置流程
  15. Java笔记:Java的三种页面跳转方法(setHeader,SendRedirect,forward)
  16. forward 和 redirect 有什么区别 区别是什么?
  17. windows查看端口
  18. Arista-CVP初始化
  19. Terminal-笔记-1.0
  20. html中的body标签

热门文章

  1. 并发请求数_nginx如何限制并发连接和请求数?
  2. mysql将查到的数据删除_MySQL数据库的基本操作——增、删、改、查
  3. PAT_B_1017_Java(20分)
  4. azdb文件怎么打开_AZDBMappingSvcs.dll
  5. CF--思维练习--CodeForces - 216C - Hiring Staff (思维+模拟)
  6. HBuilder、HBuilderX连接夜神模拟器
  7. [深度学习] 自然语言处理 --- Self-Attention(二) 动画与代码演示
  8. lwIP ARP协议分析
  9. 【Transformer】ViT:An image is worth 16x16: transformers for image recognition at scale
  10. FPGA嵌入式处理器的选择策略