约瑟夫环问题分析

问题描述

现有n个人围城一个环,并从0到n-1编号;由第一个人从0开始报数,报到m-1的人出列,之后下一个人又从0开始报。问最后剩下的那个人的编号是多少?

分析

现有n个人,编号分别是(0、1、2、3…m、m+1…n-1),这也是他们报数的序列;当出列一个人后,下一个人就要从0开始数,新的报数序列将变为:m+1–>0,m+2–>1,,n-1–>n-m-2,1–>n-m-1,2–>n-m,,m-1–>n-2共n-1项;令f(n)[i]为有n个人时第i个人该报多少;f(n-1)[i]与f(n)[i]的关系就是:f(n)[i] = (f(n-1)[i]+m)%n;例如:上例有n-1个人时报数字1的人,在有n个人时他要报(2+m)%n=m+2;因为第一次的报数序列就是这n个人的编号,而最后剩下一个人时,这个人应该报0。所以要求最后剩下的人的编号,直接算f(n)[0] = (f(n-1)[0]+m)%n;
由于每次都是求第一个编号,所以可以直接省去后面的"[0]",写成f(n)=(f(n-1)+m)%n;其中f(1)=0;直接从1开始向上求解,O(n)的算法。

int Josephus(int n,int m){
    int f = 0;
    for(int i = 2;i<=n;i++){
        f = (f+m)%i;
    }
    return f;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值