Ackerman问题

Ackerman问题:

 

ackerman(m,n)=    (n+1)     [m=0]

                             ackerman(m-1,1)   [m<>0, n=0]

                             ackerman ( m-1 , ackerman(m , n))   [m<>0, n<>0]

 

 1 int ackerman(int m, int n) //递归算法

 2 {

 3     if (m==0)

 4     {

 5         return n+1;

 6     }

 7     else if (n ==0 )

 8     {

 9         return ackerman(m-1, 1);

10     }

11     else

12     {

13         return ackerman(m-1, ackerman(m, n-1));

14     }

15 }

16 

17 #define ACKER_MAX_M    100

18 #define ACKER_MAX_N 1000

19 

20 int ackerman_loop(int m, int n) //通过记录每一项消除递归,并非"递归转非递归"方式

21 {

22     assert(m>=0 && n>=0);

23     assert(m<ACKER_MAX_M && n< ACKER_MAX_N);

24 

25     int i,j;

26     int tmp[ACKER_MAX_M+1][ACKER_MAX_N+1] = {0};

27 

28     //ackerman(m,n)可能需要到ackerman(x,y)的值,其中x<m 而y可能比n要大

29     //例如: ackerman(3,0) 需要ackerman(1,3) 的值所以别以为只需要求ackerman(0..2, 0)的值就够了

30     //所以虽然m,n 限制在 ACKER_MAX_M(N)内, 但是所需要求的n不能太大,否则将越界

31     for (i=0; i<= ACKER_MAX_N; i++) 

32     {

33         tmp[0][i] = i+1;

34     }

35 

36     for (i=1; i<m+1; i++)

37     {

38         tmp[i][0] = tmp[i-1][1];

39         for (j=1; j<ACKER_MAX_N && tmp[i][j-1] < ACKER_MAX_N; j++)

40         {

41             tmp[i][j] = tmp[i-1][ tmp[i][j-1] ];

42         }

43     }

44 

45     

46     return tmp[m][n];

47 

48 }

49 

50 static int acker_memo[ACKER_MAX_M][ACKER_MAX_N] = {0};

51 int ackerman_memo(int m, int n)//动态规划中备忘法,对比上述非递归算法, 这里可以省去不需要计算的消耗

52 {

53     assert(m<ACKER_MAX_M && n<ACKER_MAX_N);

54     int tmp;

55     if (acker_memo[m][n] != 0)

56     {

57         return acker_memo[m][n];

58     }

59     if (m==0)

60     {

61         tmp =  n+1;

62     }

63     else if (n ==0 )

64     {

65         tmp = ackerman(m-1, 1);

66     }

67     else

68     {

69         acker_memo[m][n-1] = ackerman(m, n-1);

70         tmp = ackerman(m-1, acker_memo[m][n-1]);

71     }

72 

73     return acker_memo[m][n] = tmp;

74 }

在动态规划中,常用的一招,如果只需要求最优值(不需要记录其的解过程)则可以压缩内存的使用。可以将ackerman_loop中的内存使用量压缩为一个一维数组分量大小为ACKERMAN_MAX_N;(思考:ackerman_memo可不可使用压缩呢?)

将递归化为非递归的方法也是一招。。。

你可能感兴趣的:(rman)