2019独角兽企业重金招聘Python工程师标准>>>
(1)ACK(0, N)=1+N
(2)ACK(M,0)= ACK(M-1, 1)(M>0)
(3)ACK(M, N) = ACK(M-1,ACK(M, N-1)) (M>0, N>0)
试用手工求解ACK(3, 7) 的值。
因为这个函数是用递归方式定义的,如果使用递归算法编程求解并不困难。但是,要解这个具体问题,还必须经过将近 70万次 (693964次) 递归调用 !
显然,局限于递归算法,要想用手工求解这个问题是极其困难的,甚至是不可能的!
要想能用手工求解这个困难问题,唯有另想办法,另辟蹊径。
本文给出手工求解这个难题的一种高效算法。
这种高效率算法的基本思路是:先将这个二元函数 ACK(M,N) 的函数值排成一个对应的M行N列的二维数组,并将此数组每一行视为一个数列。只要能求得第M- 1行对应数列的首项值和通项公式:
ACK(M-1,0)和 ACK(M-1,N)= f(N),
然后,根据式 (2)和式 (3),即可以得到第M行对应数列的首项值
ACK(M,0)= ACK(M-1, 1)
和数列中相邻项的关系公式:
ACK(M,N)= ACK(M-1,ACK(M, N-1))= f [ACK(M,N-1)]
据此,依次推导出M=0,M=1,M=2时对应的数列通项公式后,即可以得到待求的 ACK(3,4) 的函数值了。
(注意:因为各个数列首项N=0,对应的 n=1,所以有:n= N+1。)
具体求解步骤如下:
1、式(1)就是M=0对应通项公式。这是一个首项的值为 1,公差为1的等差数列。
2、推导M=1对应数列的通项公式。
由式(2)和式(1)可得到数列的首项(N=0)的值为:
(4)ACK(1,0)=ACK(0,1)=1+1=2
由式(3)和式(1)可得到数列中相邻两项的关系公式为:
(5)ACK(1,N)= ACK(1,N-1)+ 1
(6)ACK(1,N)= 2 + N 。
3、推导M=2对应数列的通项公式。
由式(2)和式(6)可得到数列的首项(N=0)的值为
(7)ACK(2,0)=ACK(1,1) =2+1= 3 ,
由式(3)和式(6)可得到数列相邻项的关係公式:
(8)ACK(2, N)= ACK(1,ACK(2, N-1))= 2 + ACK(2, N-1)
显然,这是一个公差为2 的等差数列。
综合式(7)和式(8)得到:M=2对应的数列是一个首项为3,公差为 2的等差数列。通项公式为:
(9)ACK(2,N)=3 + 2*N 。
4、等待求值的ACK(3, 7)属于M=3对应的数列。为了求ACK(3, 7)的值,先推导M=3对应数列的首项(N=0)值和数列相邻项的关係公式。
由式(2)和式(9),可得到数列的首项(N=0)的值为
(10)ACK(3,0)=ACK(2,1)=3 + 2*1=5
由式(3)和式(9)可得到数列相邻项的关係公式:
(11) ACK(3, N)= ACK(2,ACK(3, N-1))= 3 + 2*ACK(3, N-1) 。
根据M=3对应数列的这个两个基本特牲,有两种可供选择的求值方法。
方法一:求数列通项公式法。
式(11)表明:当M=3时对应的数列,它的相邻项之间的关系是一种典型的线性关系,其通式为:
An+1= K* An + B 。(K和B是常数)。
下面讨论:在这样的相邻项关系条件下的数列通项公式推导方法。
1、当K=0时,这是一个常数列:An = B ;
2、当K=1,B=0时,这也是一个常数列:An = A1 ;
3、当K≠1,B=0时,这是一个公比为K的等比数列,An =Kn -1 *A1 ;
4、一般情况(当K≠0,1,B≠0时):
A2 =K* A1 + B
A3 =K* A2 + B=K*(K* A1 + B)+ B=K2 *A1 + B*K + B
… …
An =Kn -1 *A1 + ( B*K n -2 + B*K n -3 + … + B*K 1+ B )
注意 :括号中就是“首项为B,公比为K的等比数列的前(n -1)项之和”!
根据等比数列的前(n -1)项的求和公式,得到括号中的求和结果
Sn= B*= *Kn –1 - ,
从而得到结论:当相邻项之间的关系是An+1= K* An + B 时,数列的通项公式为
(12) An =Kn -1 *A1 + Sn=Kn -1 *(A1+)- 。 ( n=1,2,3, …)
具体到本文的问题,对照(10)式和(11)式知道:A1 = ACK(3, 0) = 5, K=2,B=3。
代入(12)式,并注意到 n=N+1, 就可以得到M=3对应数列的通项公式 :
(13) ACK(3,N) = 2N*(5+)- = 2N + 3 - 3。
将N=7代入(13)式,立即得到答案:
ACK(3,7)= 27+ 3 - 3 = 1021 。
方法二:递推法。
根据(10)式知道:A1 = ACK(3,0)=5,
再根据(11)式: ACK(3, N)= 3 + 2*ACK(3, N-1) 逐项进行递推求解:
ACK(3,1)=2*5+3=13
ACK(3,2)=2*13+3=29
ACK(3,3)=2*29+3=61
ACK(3,4)=2*61+3=125
ACK(3,5)=2*125+3=253
ACK(3,6)=2*253+3=509
ACK(3,7)=2*509+3=1021