裸的约瑟夫环问题
共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