约瑟夫环 O(n)纯数学算法 真牛X

这篇文章也是看了别人发的 我分析了一下,想了半天,才弄出点眉目来,其实也没有想象的那么难理解,

根据我的理解:应该算是个dp问题,原文中部分内容如下:

 

 

变换后就完完全全成为了(n-1)个人报数的子问题,假如我们知道这个子问题的解:例如x是
最终的胜利者,那么根据上面这个表把这个x变回去不刚好就是n个人情况的解吗?!!变回
去的公式很简单,相信大家都可以推出来:x’=(x+k)%n

如何知道(n-1)个人报数的问题的解?对,只要知道(n-2)个人的解就行了。(n-2)个人的解
呢?当然是先求(n-3)的情况 —- 这显然就是一个倒推问题!好了,思路出来了,下面写
递推公式:

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

递推公式
f[1]=0;
f[i]=(f[i-1]+m)%i;  (i>1)

有了这个公式,我们要做的就是从1-n顺序算出f[i]的数值,最后结果是f[n]。因为实际生
活中编号总是从1开始,我们输出f[n] + 1

由于是逐级递推,不需要保存每个f[i],程序也是异常简单:

#i nclude <stdio.h>

main()
{
  int n, m, i, s=0;
  printf (“N M = “); scanf(“%d%d”, &n, &m);
  for (i=2; i<=n; i ) s=(s + m)%i;
  printf (“The winner is %d/n”, s+1);
}

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lvroyce/archive/2009/02/13/3883760.aspx

 

 

其实这句话最关键:

 

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

 

根据dp问题,求n个问题的最优解,可以根据n-1个问题的最优解,一直到1个问题,看似是一个递归过程,但是如果用递归过程的话,会提高算法复杂度,这个问题还算比较简单,容易分析,根据上面博主的推导,采用自底向下分析的方法,先求出2个元素时哪个元素是最优解,然后再将最优解保留,与第三个元素一起算出3个元素时的最优解,所以一直到n-1个元素时,算出的最优解与第n个元素合并算出整个过程的最优解,也就是博主所说的将n-1个元素的最终的胜利者x变回去的说法。

 

如果有错误请各位指出~~~ 我只是分析了一下

    原文作者:约瑟夫环问题
    原文地址: https://blog.csdn.net/jakiejiajia/article/details/5451673
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞