递推算法和递归算法,虽然叫法不一样但基本思想是一致的。一般来说借助循环语句的递推算法,要比借助调用自身函数的递归算法速度更快(因为递归是一个往返),递归算法比递推算法更容易阅读。(明天写递归)
·递推算法
典型的,如斐波那契数列问题(每一项的数值都是前两项数值之和),重点在于找出不同数据间的关系,可以分为顺推(从已知条件出发,推算出要解决的问题)、逆推(从已知问题的结果出发,推算要解决的问题)
1.钓鱼问题。六个人钓鱼,第一个人说自己比第二个人多钓2条,第二个人说自己比第三个人多钓2条......每一个人都说自己比下一个人多钓2条,问到第六个人时,他说自己钓了3条,问第一个人钓鱼了几条。
【我们可以根据已知条件出发,在第六个人的基础上+2得出第五个,在第五个的基础上+2得出第四个,以此类推。记得循环的次数是人数-1,6个人只需要从第六个人往前推5次】
ans=int(input())
people=int(input())
for i in range(people-1):
ans=ans+2
print(ans)
2.猴子吃桃。猴子摘下若干桃子,每天吃桃子的一半加一个,到第十天发现只剩下一个桃子,问当初摘了多少个桃子。
【已知最后剩1个桃子,那么前一天就是1+1的二倍个桃子,以此类推从第十天往前推九次得最初摘下的桃子数】
ans=int(input())
days=int(input())
for i in range(days-1):
ans=(ans+1)*2
print(ans)
3.棋盘格数。设有一个n行m列的棋盘(1≤n≤100,1≤m≤100),求出该棋盘分别包含多少个正方形、多少个长方形。
【数其中正方形数量时的规律:
边长为1的正方形的个数为:n*m
边长为2的正方形的个数为:(n-1)*(m-1)
边长为3的正方形的个数为:(n-2)*(m-2)
......
我是这么理解的,原本1行/1列就能代表一个正方形。以一行为例,正方形边长增加后,为了能划出更多的正方形避免不了会有重叠(最好的情况下只和上一个正方形错开一行,这样看好像一行还是代表一个正方形),可到边界最后一个正方形时,不存在下一个正方形和他重叠,于是会浪费掉正方形边长数-1行。每一列同理。
单独求长方形个数有些困难,但根据长宽关系求包含正方形和长方形的总和却比较简单,设包含长方形和正方形个数的总和为S,包含长方形个数为S1,包含正方形个数为S2,则S1=S-S2
(故此处视正方形为特殊的长方形)
若宽为1,长为m,第一行有1个长方形符合要求
若宽为1,长为m-1,第一行有2个长方形符合要求
若宽为1,长为m-2,第一行有3个长方形符合要求
......
若宽为1,长为1,第一行有m个长方形符合要求
~~则宽为1的情况下,长方形个数为(1+2+3+......+m)*n
若宽为2,长为m,前两行有1个长方形符合要求
若宽为2,长为m-1,前两行有2个长方形符合要求
若宽为2,长为m-2,前两行有3个长方形符合要求
......
若宽为1,长为1,前两行有m个长方形符合要求
~~则宽为2的情况下,长方形个数为(1+2+3+......+m)*(n-1)
......
~~则宽为3的情况下,长方形个数为(1+2+3+......+m)*(n-2)
......
~~则宽为n的情况下,长方形个数为(1+2+3+......+m)*1
将以下情况相加,提取公因式,即(1+2+3+......+m)*(1+2+3+......+n)
运用等差数列求和公式,乘号左边为m*(1+m)/2,乘号右边为n*(1+n)/2
所以(1+2+3+......+m)*(1+2+3+......+n)=(1+m)*(1+n)*m*n/4
然后进行编码即可】
(由此可见挖掘数学关系在编码过程中是多么重要啊)
n=int(input())
m=int(input())
m1=m
n1=n
S1= n*m
while (m1!=0)and(n1!=0):
m1=m1-1
n1=n1-1
S1=S1+m1*n1
S2=((m+1)*(n+1)*m*n)//4-S1
print(S1)
print(S2)
------未完待续
明天过一下递归,就要返回去再练习一下前两天学的算法,温故知新。