zoukankan      html  css  js  c++  java
  • 约瑟夫环问题的递归实现

    约瑟夫环问题有很多实现方法,迭代啦,递归啦。

    这里主要介绍一下递归的方法。

    假设:

    初始情况: 0, 1, 2 ......n-2, n-1 (共n个人)

     第一个人(编号一定是(m-1)%n,设之为(k-1) ) 出列之后,

    剩下的n-1个人组成了一个新的约瑟夫环(以编号为k==m%n的人开始):

     k  k+1  k+2  ... n-2, n-1, 0, 1, 2, ...,k-3, k-2 


    现在我们把他们的编号做一下转换:


    x' -> x      (x‘代表新编号,x代表原编号   k==m%n

    k     --> 0
    k+1   --> 1
    k+2   --> 2
    ...
    ...
    k-2   --> n-2
    k-1   --> n-1

    变换后就完完全全成为了(n-1)个人报数的子问题,假如我们知道这个子问题的解:例如x是最终的胜利者,那么根据上面这个表把这个x变回去不刚好就是n个人情况的解吗!


    x ->x'?(这正是从n-1时的结果反过来推n个人时的编号!)
    0 -> k

    1 -> k+1

    2 -> k+2

    ...

    ...

    n-2 -> k-2

    变回去的公式 x'=(x+k)%n


    那么,如何知道(n-1)个人报数的问题的解?只要知道(n-2)个人的解就行了。(n-2)个人的解呢?只要知道(n-3)的情况就可以了 ---- 这显然就是一个递归问题:


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


    递推公式


    f[1]=0;

    f[n]=(f[n-1]+k)%n = (f[n-1] +m%n) % n = (f[n-1] + m) % n ;  (n>1)

    当然,当n==1时,直接返回0即可

    代码如下:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 int Josephus(int n,int m){
     5     if(n>1){
     6         return (m+Josephus(n-1,m))%n;
     7     }
     8     else{
     9         return 0;
    10     }
    11 }
    12 int main()
    13 {
    14     int n,m;
    15     scanf("%d %d",&n,&m);
    16     int result=Josephus(n,m);
    17     printf("%d",result+1);
    18 
    19     return 0;
    20 }
    有些目标看似很遥远,但只要付出足够多的努力,这一切总有可能实现!
  • 相关阅读:
    客户细分那点事_实践1
    和各种人去交流_好玩的事
    客户细分那点事_理论篇
    模型持久化
    天赋是积累出来的——转载自周鸿祎博客
    Pytorch——torch.nn.Sequential()详解
    第2章 Python序列
    Pytorch将数据打包
    线性回归的从零开始实现
    plt.scatter 各参数详解
  • 原文地址:https://www.cnblogs.com/Bravewtz/p/10089717.html
Copyright © 2011-2022 走看看