• 约瑟夫环问题的递归实现


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

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

    假设:

    初始情况: 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 }
    有些目标看似很遥远,但只要付出足够多的努力,这一切总有可能实现!
  • 相关阅读:
    Django admin修改密码
    Python中查看函数相关文档
    Python之False和None
    前端神器之jquery
    网页三剑客之JS
    Python常用模块-时间模块
    python静态方法和类方法
    数据库学习之MySQL基础
    lmbench的使用方法
    sd卡无法启动及zc706更改主频后可以进入uboot无法启动kernel的坑
  • 原文地址:https://www.cnblogs.com/Bravewtz/p/10089717.html
Copyright © 2020-2023  润新知