常见的一个经典问题:
从格子外面朝着格子里面跳,请问假定如果每次只能跳一个格子或者两个格子,跳到第八个格子有多少种不同的跳法?
数学的想法
这是一个关于数列的题,可以这样去想一个存在递归的问题:
假如我要跳到第
n
n
n 个格子,那么就必须要在前一步跳到第
n
−
1
n-1
n−1 或者
n
−
2
n-2
n−2 个格子,如果说跳到第
n
n
n 个格子用的次数为
a
n
a_n
an ,那么
a
n
=
a
n
−
1
+
a
n
−
2
a_n = a_{n-1}+ a_{n-2}
an=an−1+an−2。
注意,在这个地方有一个理解问题,为什么在等式的右侧没有系数:尽管
n
−
2
n-2
n−2 能够通过移动一个格子移动到
n
−
1
n-1
n−1 的位置,但是这样会导致计算的重复性,因此前面不加系数,直接可以默认为从
n
−
2
n-2
n−2 个格子是跳一次移动两个格子到
n
n
n 的这个位置。
那么,根据这样的想法,去求解这个数学问题就很简答了,就直接是斐波那契数列了:对于前面的跳格子的跳法进行计算,后面的就可以根据前面两项进行求和计算。
格子数 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
跳法 | 1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 | 55 | 89 |
当然,如果是步长设置最长为3,那么就相当于这个项的前面三项的值进行求和即可
格子数 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
跳法 | 1 | 2 | 4 | 7 | 13 | 24 | 44 | 81 | 149 | 274 |
以此类推,后面的格子可以根据前面的格子跳法来求和进行计算。
代码
运用代码来写递归的方式同样可以计算
python代码如下 代码片
:
def get_num(i):
k = input('请输入{}(若希望终止请输入 \'False\') :'.format(i))
k = k.upper()
if k == 'FALSE':
return False
try:
k=float(k)
except ValueError as reason:
print('输入有误,请输入整数值:')
return get_num()
if k==int(k):
k=int(k)
return k
else:
print('输入有误,您输入的数值为浮点数,请输入整数值')
return get_num()
def get_point():
point = {}
point_name = ['终点','最大步长']
for i in point_name:
point[i] = get_num(i)
if point[i] is False:
return False
return point
def num_count(begin_point,end_point,max_step):
if begin_point>end_point:
return 0
if begin_point==end_point:
return 1
else:
return sum([num_count(begin_point+1+i,end_point,max_step) for i in range(max_step)])
if __name__=='__main__':
point = get_point()
if point is False:
print('输入的内容有误,程序已经终止')
else:
end_point = point['终点']
max_depth = point['最大步长']
begin_point = 0
num = num_count(begin_point,end_point,max_depth)
a ='='*50
print('\n',a,end='\n\n')
print('起始点为:{}\n终点为:{}\n最大步长为:{}'.format(begin_point,end_point,max_depth))
print('所走的总的不同选择有 {} 种'.format(num))