zoukankan      html  css  js  c++  java
  • 由约瑟夫问题到一类特殊的递归式

    由约瑟夫问题到一类特殊的递归式

    参考资料:《具体数学》


    前言:

    其实。。本文和约瑟夫问题没什么关系。。题目是吸引你点进来的


    正文:

    约瑟夫问题

    这个,大家应该都知道吧,不知道的可以看一看这个

    下面是约瑟夫问题的一个简化版本:

    有n个人围成一个环,依次编号为1到n,然后1,2报数,报到2的人出列,求最后出列的人的编号。

    首先,我们打表找规律一下,规定J(n)表示n个人的约瑟夫问题中最后出列的人的编号。

    n J(n)
    1 1
    2 1
    3 3
    4 1
    5 3
    6 5
    7 7
    8 1
    9 3
    (cdots) (cdots)

    好像,全是奇数?

    其实,在第一轮时,转一圈后所有的偶数都出列了,剩下的当然只有奇数。

    那么我们考虑一下转一圈后的情况:

    当n为偶数时,转一圈删掉了n后又回到了1号,这时,原来编号为i的人的位置现在的人的编号变成了2*i-1,所以我们可以得到:

    [J(2n)=2J(n)-1 ]

    当n为奇数时,转一圈删掉了n-1后又删掉了1号,来到了3号,这时,原来编号为i的人的位置现在的人的编号变成了2*i+1,所以我们可以得到:

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

    综合以上内容,我们可以得到下面的式子:

    [J(1)=1 ]

    [J(2n)=2J(n)-1 ]

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

    有了这个式子,我们就可以快速计算J(n)了。但是我们还是不满足,递归式算起来还是太麻烦,有没有更好的方法呢?

    我们在观察上面的表,有没有发现什么呢?

    1,1,3,1,3,5,7,1,3...

    1,1,3,1,3,5,7,1,3,5,7,9,11,13,15,1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,1!

    好像。。按2的幂次分组,然后每一个都是前一个加二!

    [J(n)=2l+1 , n=2^m+l , lin[0,2^m) ]

    可以归纳一下:

    首先,1很明显符合该性质。

    现在假设前i-1符合这个性质,那么

    如果i为偶数,则:

    [J(n)=2J(frac{n}{2})-1=2(2frac{l}{2}+1)-1=2l+1 , n=2^m+l , lin[0,2^m) ]

    如果i为奇数,则:

    [J(n)=2J(frac{n-1}{2})+1=2(2frac{l-1}{2}+1)+1=2l+1 , n=2^m+l , lin[0,2^m) ]

    证毕。

    还有什么性质吗?

    不妨从二进制的眼光来看一看这个问题:

    (n=(1b_{m-1}cdots b_1b_0)_2)

    (2^m=(10cdots 00)_2)

    (l=(0b_{m-1}cdots b_1b_0)_2)

    (J(n)=2l+1=(b_{m-1}cdots b_1b_01)_2)

    J(n)是n循环左移了一位!


    约瑟夫问题讲完了,还有吗?

    当然还有了,你没看见题目吗?

    一类特殊的递归式

    虽然我们成功的解决了约瑟夫问题的一种简单形式,并能够在(O(1))(m确定)或(O(loglogn))(m不确定)的时间复杂度内解决,但是我们还远远没有满足。不妨再来看看这个递归式:

    [J(1)=1 ]

    [J(2*n)=2J(n)-1 ]

    [J(2*n+1)=2J(n)+1 ]

    太特殊了,我们来看看这个:

    [f(1)=alpha ]

    [f(2*n)=2f(n)+eta ]

    [f(2*n+1)=2f(n)+gamma ]

    容易看出,前面的就是(alpha =1,eta =-1 ,gamma =1)的特殊情况。怎么办?

    当然还是打表了。

    n f(n)
    1 (alpha)
    2 (2alpha + eta)
    3 (2alpha + gamma)
    4 (4alpha + 3eta)
    5 (4alpha+2eta+gamma)
    6 (4alpha+ eta+2gamma)
    7 (4alpha +3gamma)
    8 (8alpha+7eta)
    9 (8alpha+6eta+gamma)
    (cdots) (cdots)

    有了上面的经验,这次就简单一点了。

    首先按二的幂次分组,然后大力猜结论。

    我们设(f(n)=A(n)alpha+B(n)eta+C(n)gamma),剩下的就是求出来(A(n),B(n),C(n))

    当然,我们还是可以归纳,但是在这里,我们可以用一些更简单的方法:

    我们令(alpha =1,eta=0,gamma=0),那么原递归式就变成了

    [f(1)=1 ]

    [f(2*n)=2f(n) ]

    [f(2*n+1)=2f(n) ]

    易知,(f(n)=2^m ,n=2^m+l,lin[0,2^m))

    (f(n)=A(n))

    所以(A(n)=2^m)

    然后我们令(f(n)=1)

    [1=alpha ]

    [1=2*1+eta ]

    [1=2*1+gamma ]

    解得(alpha=1,eta=-1,gamma=-1)

    所以(f(n)=A(n)-B(n)-C(n)=1)

    (f(n)=n)

    [1=alpha ]

    [2n=2n+eta ]

    [2n+1=2n+gamma ]

    解得(alpha=1,eta=0,gamma=1)

    于是得到方程:(A(n)+C(n)=n)

    所以:

    [left { egin{array}\ A(n)&=2^m\ A(n)-B(n)-C(n)&=1\ A(n)+C(n)&=n end{array} ight . ]

    解得:

    [A(n)=2^m,B(n)=2^m-l-1,C(n)=l ]

    小总结:解递归式时可以带入几个比较特殊的数或者是函数,来帮助我们计算,可以减少我们找规律然后再归纳的时间。

    这样就行了?

    当然不行。

    上面我们找到了关于2进制的性质,那么现在有没有呢?

    当然有了,为什么没有呢。

    我们设(eta_0=eta,eta_1=gamma),带到原递归式里看一看吧。。

    [egin{array}\ f((b_mb_{m-1}cdots b_1b_0)_2)&=2f((b_mb_{m-1}cdots b_1)_2)+eta_{b_0}\ &=4f((b_mb_{m-1}cdots b_2)_2)+2eta_{b_1}+eta_{b_0}\ &=cdots\ &=2^malpha+2^{m-1}eta_{b_{m-1}}+cdots+2eta_{b_1}+eta_{b_0} end{array} ]

    如果2进制位里面不止可以填01的话,那就相当于:

    [f((b_mb_{m-1}cdots b_1b_0)_2)=(alphaeta_{b_{m-1}}cdotseta_{b_1}eta_{b_0})_2 ]

    这样还不够,这并不是我们的一类递归式。真正的递归式在下面:

    [f(i)=alpha_i ,iin[1,c) ]

    [f(cn+i)=df(n)+eta_i,iin[1,c) ]

    这个跟上面的是差不多的。直接扔结论:

    [f((b_mb_{m-1}cdots b_1b_0)_c)=(alpha_{b_m}eta_{b_{m-1}}cdotseta_{b_1}eta_{b_0})_d ]

    现在差不多了。我才不会告诉你我就会这些。

    例题:有递归式:

    [egin{array}\ f(1)&=34\ f(2)&=5\ f(3n)&=10f(n)+76,\ f(3n+1)&=10f(n)-2\ f(3n+2)&=10f(n)+8\ end{array} ]

    求f(17)

  • 相关阅读:
    字符数组,字符指针,字符串常量以及其sizeof的一些总结
    Linux——makefile
    动态定义多维数组
    二叉树的前序、中序、后序遍历(非递归)
    构造函数、析构函数抛出异常的问题
    倒排索引
    宏定义
    sizeof && strlen
    搜索引擎技术原理
    最小生成树
  • 原文地址:https://www.cnblogs.com/shanxieng/p/10044861.html
Copyright © 2011-2022 走看看