约瑟夫问题

博客探讨了约瑟夫问题的解决方案,包括递归公式J(2n)=2J(n)-1和J(2n+1)=2J(n)+1,并通过二进制表示揭示了幸存者编号的循环移位规律。此外,还讨论了如何将这种方法拓展到更一般的形式f(n),并给出了其他递归式的解题思路。

今天闲着无聊整理下《具体数学》中关于约瑟夫问题的讨论。

n个人围成一圈,从1n标号,每隔一个人处死一个人,求最后幸存下来的人的编号,例如n=10,则被杀的人按顺序依次是:

2,4,6,8,10,3,7,1,9

当然可以直接模拟杀人的过程直到剩下最后一个,但这种方法不够快。

可以考虑递归做法,如果杀了一圈,那么这个时候我们可以把剩下的人从1开始重新排列,这样如果能够找到两次排列的编号关系,就可以用递归来解决了。

假设n为偶数,那么因为隔一个杀一个,因此,所有标号为偶数的人都会被杀掉,因此,我们如果将剩下幸存的人重新标号可得:

n=10为例,

杀之前: [1,2,3,4,5,6,7,8,9,10]

杀之后: [1,  ,2,  ,3,  ,4,  ,5,    ]

其中空出来的表示在这轮中阵亡的。

可以很轻松的发现这两者之间的关系(21),因此我们可得:

假设J(n)n个人的约瑟夫环最后剩下的幸存者的编号,因此有

J(2n)=2J(n)1

同理如果是奇数呢

n=9为例,

杀之前: [1,2,3,4,5,6,7,8,9]

杀之后: [  ,  ,1,  ,2,  ,3,  ,4]

其中空出来的表示在这轮中阵亡的。

因此,我们也可以得到他们之间的关系:(2+1),所以有:

J(2n+1)=2J(n)+1

因此合起来我们可以得到递推式:

J(2n)=2J(n)1

J(2n+1)=2J(n)+1

n=1时,则有J(n)=1

接下来求J(n)的闭形式:

根据J(2n)=2J(n)1,且J(1)=1可得,J(2m)=1恒成立,因此假设对于所有的数都能表示为2m+l0l<2m,则有

J(2m+l)=2l+1

这是因为,如果杀了l个人,此时,剩下的人数则为2m个,因此,此时幸存的人应该是第l个被杀的人的后一个,因此也就是2l+1

在书中,作者是用了猜想+数学归纳法的方法来证明这个式子的,之后他发现了一个有趣的模式:

如果用二进制表示递推式,可得:

n=(1bm1bm2...b1b0)2

l=(0bm1bm2...b1b0)2

2l+1=(bm1bm2...b1b01)2

因此最后可得:

J((bmbm1...b1b0)2)=(bm1...b1b0bm)2

也就是将人数n的二进制形式向左循环移动一位,就可以得到幸存的人的编号,通过这也就可以得出如果当人数为2m1时,最后一个人将幸存。

接下来拓展一下,可以解决形如:

f(1)=α

f(2n+j)=2f(n)+βj

其中j=0,1n1

的问题:

假设n=(bmbm1...b1b0)2

则可以不断把最后一位提出来:

f((bmbm1...b1b0)2)=2f((bmbm1...b1)2)+βb0


=2mα+2m1βbm1+...+2βb1+βb0

第一位是α的原因在于bm=1

于是就有了如下的结论:

f(bmbm1...b1b0)2=(αβbm1βbm2...βb1βb0)2

回到约瑟夫问题,这是当α=1,β0=1,β1=1时的特例,可以发现,当n写成(βmβm1...β1β0)2时,我们可以把它分成若干段(10...00)2,而每段都会变成(11...11)2=(00...01)2,这也就说明了向左循环移位的事实。

例如,当n=100时,有n=(1100100)2,因此可以分解成三段:(1)2,(100)2,(100)2,而每段变换后分别得到(1)2,(001)2,(001)2,合起来后变成(1001001)2,也就相当于进行了向左循环移位。

当然我们可以再弱化一下递归式,变成:

f(j)=αj,                        1j<d

f(dn+j)=cf(n)+βj, 0j<d,n1

我们同样可以假设此时的n可以表示为n=(bmbm1...b1b0)d,然后用同样方法展开:

    f((bmbm1...b1b0)d)

=cf((bmbm1...b1)d)+βb0

=c2f((bmbm1...b2)d)+cβb1+βb0

...

=cmαbm+cm1βbm1+...+cβb1+βb0

=(αbmβbm1βbm2...βb1βb0)c

f((bmbm1...b1b0)d)=(αbmβbm1βbm2...βb1βb0)c

所以遇到这种类型的递归式,只需要做进制数的改变就行了。
例如,有递归式

f(1)=34

f(2)=5

f(3n)=10f(n)+76,(n1)

f(3n+1)=10f(n)2,(n1)

f(3n+2)=10f(n)+8,(n1)

且我们要求解f(19),因为d=3,c=10,因此,

f(19)=f((201)3)=(5,76,2)10=5102+761012100=1258
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值