约瑟夫环

裸的约瑟夫环问题

共n个人,从1开始报数,报到k的人从环中退出,问最后剩下的一个人的编号是多少?

这种问题应该这样考虑:假设n个人的编号为0-n-1

第一次第k-1的人走了,那么下一轮的时候我们就要重新给这n-1个人编号,第二轮第k个人现在编号为0,那么此时的第k-1个人第一轮的编号应该是(f[1]+k-1)%i2。依次类推,那么最后剩下来的人编号肯定是0.通过向前递推,得到其原来的编号。

假设该轮有 n 个人,那么上一轮 (n+1) 人,编号为 0 的人上一轮编号为k,也即编号为 f[n] 的人上一轮编号为 (f[n]+k)%(n+1)
我们知道最后剩下的人在最后一轮编号肯定为0,那么这样不断倒推就可以推出其在第一轮的编号,也即他本来的编号。

f[1]=0;

for(int i=2;i<=n;i++)

  f[i]=(f[i-1]+k)%i;

f[n]就是答案

现在如果是这样的一个问题:

还是n个人,每次从1开始报数,第一次报1的人离开了,第二次报二的人离开,。。。第n-1次报n-1次的人离开了,谁会最后留下来?

还是一样的问题。最终的状态那个人的编号肯定为0,那么我们需要往前递推,得到他最初的编号。那么上一轮k是n-1;再上一轮k是n-2;依次k为1

int k=n-1;

f[1]=0;

for(int i=2;i<=n;i++)//n-1轮

f[i]=(f[i-1]+k--)%i

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值