《具体数学》——递归问题

以后的搬砖转化一下思路,以一本书为主体,进行类似读书笔记式的讨论和总结,首先便从这本高德纳的《具体数学》开始吧。

大致翻了一下这本书,能够明显感觉到大师所著的书和国内的一些出版物是没办法比的。看了一下这本书的序言,发现这本书有一个很大的特色就是“数学涂鸦”,好像是有一部分读者在阅读该书时的注释被收录到了这本书当中,这些涂鸦中不仅仅有俏皮的玩笑,还不乏精巧的解题方略,与作者在论述清晰优雅而又诙谐的语调融为一体,大概才看了一节,感觉《具体数学》的确是一本值得仔细研读的好书。

那么下面我们便开始正式开始搬砖工作。

约瑟夫环问题。

这个问题有个很有意思的历史起源:“传说如果不是由于他的数学天赋,约瑟夫不会活到出名的那一 天.在犹太罗马战争期间,他们41名犹太反抗者困在了罗马人包围的洞穴中.这些反抗者宁 愿自杀也不愿被活捉,于是决定围成一个圆圈,并沿着圆圈每隔两个人杀死一个人,直到剩 下后两个人为止.但是,约瑟夫和一个未被告发的同谋者不希望无谓地自杀,于是他迅速 计算出他和其朋友在这个险恶的圆圈中应该站的位置。”

我们先将将这个问题抽象化成数学模型:即将n个人围成一圈,从n开始每隔1个人杀死一个,那么求解最终活下来的那个人的起始编号?

这个问题似乎进行模拟运算是可解的,但是过程太过繁杂丑陋,我们需要一些更加漂亮的数学技巧。

我们以n = 10为例来模拟这个过程,我们绕着圆周筛选一次,则2、4、6、8、10被删除,剩余1、3、5、7、9,为了方便新一轮的筛选,我们此时进行重新编号。

1 -> 1

3 -> 2

5 -> 3

7 -> 4

9 -> 5

我们设置J(n)表示约瑟夫问题的解,通过上述问题的转化我们发现,我们在模拟求解J(n)的时候,生成了一个子问题,而这个子问题又可以转化成另外一个完全独立的问题,也就是在求解J(10)的过程中,我们形成了一个1、3、5、7、9作为环的子问题,而我们又将这个子问题转化成了求解J(5),基于原问题和子问题具有同解性,再基于将子问题转化成J(5)的过程,我们容易建立起J(10)和J(5)的递推关系,即:J(10) = 2J(5) - 1。

由此我们不难进行推广,J(2n) = 2J(n) - 1。

其实讲到这里,如果理解了的话,其实掌握了解决约瑟夫环问题的核心思维了,虽然此时我们对于奇数情况还没有讨论。

我们基于这种思维,进行一个推广,对于n个人,从1开始,每次删掉m的整数倍,该如何求解呢?

类似上文的思路,这次我们缩短我们的脚步,不要一次删掉一圈再进行子问题转化,而删掉一个数后就进行子问题转化。以n = 10,m = 3为例。

第一次删除:3。

删除后的结果:1、2、4、5、6、7、8、9、10。

转化子问题:1 -> 8

2 -> 9

4 -> 1

5 -> 2

6 -> 3

7 -> 4

8 -> 5

9 -> 6

10-> 7

我们容易看到,J(10) = (J(9)   + 3) %10,我们也不难找到推广规律——J(n) = (J(n-1) + m)%n。

然后基于J(1) = 1,我们便可以对所有问题进行递推求解。

我们通过一个具体问题来应用一下这个思路。(Problem source : hdu 2925)

Problem Description

In the traditional game of Musical Chairs, N + 1  children run around N  chairs (placed in a circle) as long as music is playing. The moment the music stops, children run and try to sit on an available chair. The child still standing leaves the game, a chair is removed, and the game continues with N  children. The last child to sit is the winner.In an attempt to create a similar game on these days‘ game consoles, you modify the game in the following manner: N Children are seated on N chairs arranged around a circle. The chairs are numbered from 1 to N . Your program pre-selects a positive number D . The program starts going in circles counting the children starting with the first chair. Once the count reaches D , that child leaves the game, removing his/her chair. The program starts counting again, beginning with the next chair in the circle. The last child remaining in the circle is the winner.
For example, consider the game illustrated in the figure above for N = 5 and D = 3 . In the figure, the dot indicates where counting starts and × indicates the child leaving. Starting off, child #3 leaves the game, and counting restarts with child #4. Child #1 is the second child to leave and counting restart with child #2 resulting in child #5 leaving. Child #2 is the last to leave, and child #4 is the winner. Write a program to determine the winning child given both N and D .

Input

Your program will be tested on one or more test cases. Each test case specifies two positive integers N  and D  on a single line, separated by one or more spaces, where N, D < 1, 000, 000 .
The last line of the input file contains two 0‘s and is not part of the test cases.

Output

For each test case, write the winner using the following format:
N D W
Where N and D are as above, is a space character, and W is the winner of that game.

容易看到,这道问题基于约瑟夫环问题在数据上做了小小的变动,由于总数是n+1,那么我们便从0开始编号,即初始条件J(1) = 0。

时间: 2024-10-12 18:02:16

《具体数学》——递归问题的相关文章

LA3882 约瑟夫数学递归法

首先,约瑟夫环的数学优化方法为: 为了讨论方便,先把问题稍微改变一下,并不影响原意:问题描述:n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数.求胜利者的编号. 我们知道第一个人(编号一定是(m-1)%n) 出列之后,剩下的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 --

HDU 4472 Count(数学 递归)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4472 Problem Description Prof. Tigris is the head of an archaeological team who is currently in charge of an excavation in a site of ancient relics. This site contains relics of a village where civilizat

POJ 1759 Garland(二分+数学递归+坑精度)

POJ 1759 Garland  这个题wa了27次,忘了用一个数来储存f[n-1],每次由于二分都会改变f[n-1]的值,得到的有的值不精确,直接输出f[n-1]肯定有问题. 这个题用c++交可以过,g++交过不了, f[i]=2+2*f[i-1]-f[i-2]; f[0]=A,f[1]=x; 二分枚举x的值,最终得到B的值(不是f[n-1]), 上述递推式是非齐次的二阶递推式,解其齐次特征方程,可以得到f[n-1]的齐次时的表达式,对于非齐次的,目前我还没法求出通式, B与f[n-1]的关

“奇技淫巧” 话递归

“To Iterate is Human, to Recurs,Divine.” ---L. Peter Deutsch “迭代是人,递归是神” 第一次见有人这样说,让我受伤的心得到些许安慰...... 最近在琢磨算法,又见递归! 这是个绕不过去的坎! 当初,上大学时似懂非懂自欺欺人的蒙混过关,再次引证了那句名言:“出来混,迟早都是要还的......”.好吧,那就直面它!于是搜遍海内外,加上日思夜想,被这“奇技淫巧”折魔得真掉了不少头发(主要是8皇后问题~). 大神王垠在谈程序语言最精华的原理时

数据结构第一章

证明数据结构分析中的结论的两个常用的方法时归纳法和反证法 归纳法:第一步是证明基准情形,就是确定定理对于某个小的值的正确性,(这一步几乎是很简单的 第二部,进行归纳假设,一般来说,这意味着假设定理对直到某个有限数k的所有的情况都成立的,然后使用这个假设证明定理对于下一个值也是成立的. 反证法:通过假设定理不成立,然后证明该假设导致某一个已知性质不成立,从而说明原假设是错误的. 反证法和归纳法不同处,归纳发从基础出发,反证法从结论出发. 什么是递归:当一个函数用他自己来定义时就称为是递归. 不是所

16.05.25-16.06.10 题集

继2016.05.24续: codeforces 651B. Beautiful Paintings-简单 http://codeforces.com/problemset/problem/651/B 大意:给出一个序列,求解其任意排列中满足ai?+?1?>?ai 的元素个数最大和. 分析:理想情况下,无重复元素的0从小到大的排列,满足条件的元素个数最多,是n-1. 非理想情况下还有重复元素,只要不断提取出重复的这些元素归到另一集合再这样讨论即可. #include <iostream>

数据结构(c语言描述)

数据结构(c语言描述) 目录 预备的数学知识 什么是数据结构 线性表 栈和队列 数组 串 树和二叉树 查找 排序 预备的数学知识 等差数列求和 Sn=(a1+an)*n/2 等比数列求和 Sn=a1*(1-q?)/(1-q) 什么是数据结构 基本概念 数据: 能够被计算机识别和处理的符号的集合 数据元素:是数据的基本单位,由若干的数据项构成,如一个人有手有脚 数据对象:由同类型的数据元素组成的集合,如一群人 数据类型:由一个集合和定义在此集合上的操作组成 原子类型:值不可再分的数据类型,如int

9.20 函数 时间、数学、递归、字符串

函数:     四要素:返回类型      函数名      参数      函数体 强类型语言函数写法访问修饰符 返回类型 函数名 (参数列表){            函数体                        } 弱类型语言函数写法function 1.无参数的函数2.有参数的函数3.有返回值的函数JS常用函数日期时间函数数学函数字符串函数 递归:   递归的本质:函数自己调自己(从别处看来的笑话:要想理解递归,首先要理解递归) 日期时间函数(需要用变量调用):var b = n

【龙书笔记】用Python实现一个简单数学表达式从中缀到后缀语法的翻译器(采用递归下降分析法)

上篇笔记介绍了语法分析相关的一些基础概念,本篇笔记根据龙书第2.5节的内容实现一个针对简单表达式的后缀式语法翻译器Demo. 备注:原书中的demo是java实例,我给出的将是逻辑一致的Python版本的实现. 在简单后缀翻译器代码实现之前,还需要介绍几个基本概念. 1. 自顶向下分析法(top-down parsing) 顾名思义,top-down分析法的思路是推导产生式时,以产生式开始符号作为root节点,从上至下依次构建其子节点,最终构造出语法分析树.在具体实现时,它会把输入字符串从左到右

《具体数学》1.1递归(一)

<具体数学>通过三个例子来讲递归,分别是:Hanoi Tower(汉诺塔).Lines in the Plane(平行中的直线).Josephus Circle(约瑟夫环问题) 这三个例子一直被数学家们反复研究:已知解法都使用递归,大问题化为小问题:都可以用计算机程序来求解:我最近因为考试忙的其实也没看几页,就先把看的写出来吧; 1.1 汉诺塔 首先来看被称为"汉诺塔"(Hanoi Tower)的智力问题.该问题是法国数学家Edouard Lucas在1883年提出的.给定