• 约瑟夫问题


    问题描述

    据说著名犹太历史学家Josephus有过以下的故事:在罗马人占领乔塔帕特后,(39) 个犹太人与Josephus及他的朋友躲到一个洞中,(39)个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,(41)个人排成一个圆圈,由第(1)个人开始报数,每报数到第(3)人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过(k-2)个人(因为第一个人已经被越过),并杀掉第(k)个人。接着,再越过(k-1)个人,并杀掉第(k)个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决。Josephus要他的朋友先假装遵从,他将朋友与自己安排在第(16)个与第(31)个位置,于是逃过了这场死亡游戏。[1]

    简单描述:(0,1,cdots,n-1)(n)个数字排成一个圆圈,从数字(0)开始,每次从这个圆圈里删除第(m)个数字,并将起点标记为第(m+1)个数字,求出这个圆圈里剩下的最后一个数字。

    例如:

    输入:n = 5, m = 3

    对应数字为:0 1 2 3 4,删除的前4个数字依次为:2 0 4 1,最终剩下的数字为3。

    解决方法

    问题1(0,1,cdots,n-1),删除第(m)个数字(第(m)个数字的序号为((m-1)))后,其余数字的序号是如何改变的?

    若原序列某一位的序号为(k),删除第(m)个数字后,该数字的序号变为(k')

    (k>m-1)(该数字在被删除数字之后),则(k'=k-m)

    (k<m-1)(该数字在被删除数字之前),则(k'=n-m+k)

    综合考虑,有:(k'=(k-m)\%n)(\%)表示求余。

    问题2:已知删除第(m)个数字后,某数字的序号为(k'),此序列中剩余数字的个数为(n-1),则删除第(m)个数字前,该数字的序号是?

    根据问题1,我们已经得到了由(k)(k')的关系式,那么由(k')(k)的关系式可如下计算:

    因为:

    [k'=(k-m)\%n ]

    则:

    [k-m= au cdot n + k' ( au in Z) ]

    有:

    [k= au cdot n + k + m ]

    又已知:(k in [0, n-1])
    则:

    [k=( au cdot n + k + m)\%n=(k + m)\%n ]

    从而我们推出了由(k')(k)的关系式:

    [k=(k + m)\%n ]

    问题3:说这么多废话,约瑟夫问题到底怎么解决?

    对于最后的胜利者,也就是最终剩下的那个数字,他在这一轮的序号一定是(0)

    根据问题2中的阐述,我们可以推导出:这个胜利数字,在倒数第二轮中,他的序号是多少。(((0+m)\% 2)

    依次类推,得到如下递关系式:

    [left{ egin{array}{**lr**} F(n) = (F(n-1) + m) \% n \ F(1) = 0 end{array} ight. ]

    代码实现

    具体题目描述见 LeetCode 剑指 Offer 62

    class Solution {
    public:
        int lastRemaining(int n, int m) {
            int count = 1;
            int prev = 0;
            int curr;
            while(count <= n) {
                curr = (prev + m) % count;
                prev = curr;
                count++;
            }
            return curr;
        }
    };
    

    1. Ronald L.Graham,Donald E.Knuth,Oren Patashnik .具体数学计算机基础(第2版) :人民邮电出版社,2013:7 ↩︎

  • 相关阅读:
    使用Loadrunner监控Windows资源
    Tomcat使用线程池配置高并发连接
    性能测试中遇到的坑
    本地eclipse启动tomcat后无法访问
    Linux常用命令汇总
    Dubbo底层采用Socket进行通信详解
    今天遇到了一个Spring出现的一个未知错误,分享下
    maven pom.xml 详细
    Oracle 数据库中在使用中文模糊查询时输入中文查询不到结果的解决方法
    mybatis属性详解
  • 原文地址:https://www.cnblogs.com/xqmeng/p/13681495.html
Copyright © 2020-2023  润新知