斐波那契数
题目:
菲波那契数列是指这样的数列:数列的第一个和第二个数都为1,接下来每个数都等于前面2个数之和。给出一个正整数k,要求菲波那契数列中第k个数是多少。
输入一行,包含一个正整数k。(1 ≤ k ≤ 46)
输出一行,包含一个正整数,表示菲波那契数列中第k个数的大小。
思路:
每个数为前两个数之和,刚开始想的一直都是利用循环,利用数列求解,直接保存第一个第二个数在数列里,然后利用循坏,当前i的值为列表前两位的和,结果就是想法错误,过不去测试。 然后去搜索,查出不同的答案(有很多种,这里只描述简单的三种方法)。
- 循环(一直想到的但又没实现的,测评的效率还可以)
k=int(input())
f1,f2=1,1
current=0
if k<=2:
print(f1)
else:
for i in range(3,k+1):
current=f1+f2
f1=f2
f2=current
print(current)
有一个交换数的作用,假设i=3,current=f1+f2=2,交换数值后f1=1,f2=2(通俗来讲就是把f1,f2当作指针,刚开始指向1,1,循环一次后两个指针分别后移一位,f1就会指到f2,f2就会指到current,然后不断循环)
- 递归函数(测评效率最低,时间太长)
回忆一下,递归函数,调用函数自身的方式称为递归,例子之一是求阶乘n!
- 递归函数通常包含两个部分:基本情况 & 递归情况
- 基本情况是指当满足某个条件时,函数直接返回结果,而不再调用自身。
- 递归情况是指函数在未满足基本情况时,将问题分解为更小的子问题,并通过调用自身来解决这些子问题。
递归函数的设计和使用需要小心,因为如果没有正确定义基本情况或递归情况,函数可能会无限递归下去,导致堆栈溢出。另外,递归函数的性能比较低,因为每次函数调用都需要保存当前的执行状态。
- 什么情况下需要使用递归函数?
递归函数在许多算法和数据结构问题中非常有用,例如树的遍历、排列组合、动态规划等。通过合理地设计递归函数,可以简化问题的解决过程,并使代码更加清晰和易于理解。- 树形结构的遍历:递归函数在遍历树形结构(如二叉树、多叉树)时非常实用。通过递归调用自身,可以依次访问树的每个节点,实现先序、中序或后序遍历。
- 排列和组合问题:递归函数在排列和组合问题中也非常有用。通过递归调用自身,在每一步选择不同的元素来生成不同的排列或组合。
- 动态规划问题:动态规划是通过将大问题分解为子问题,并存储子问题的解来解决问题的方法。递归函数在动态规划问题中常常用于计算子问题的解,从而得到整个问题的解。
def fib(k):
if k<=2:
return 1
else:
return fib(k-1)+fib(k-2)
k=int(input())
print(fib(k))
效率最低,会出现大量的重复计算,时间复杂度O(1.618^n),而且最深度1000
- 尾递归函数(第一回听说(真的小白))
def fibonacci(n, a=1, b=1):
if n <= 2:
return b
else:
return fibonacci(n-1, b, a+b)
k=int(input())
print(fibonacci(k))
这里使用了默认参数的方法,其中a和b分别代表Fibonacci数列中的第n-1项和第n项。调用fibonacci(n)即可获得第n项的值。(和第一种方法本质上一样,就是交换值所实现)
尾递归是指递归函数在调用自身时直接传递其状态值。在这些语言中尾部递归不会占用调用堆栈空间。
python-递归和递推
可以见这个博主的介绍了解 ,链接:https://blog.csdn.net/weixin_43955170/article/details/115714881
校外的树
题目:
某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数轴上的每个整数点,即0,1,2,……,L,都种有一棵树。
由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。
- 输入描述:
第一行有两个整数L和 M,L代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。对于20%的数据,区域之间没有重合的部分;对于其它的数据,区域之间有重合的情况。 - 输出描述:
包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。
想法:刚开始知道怎么减,就是不知道重合部分怎么去计算 ,搜索之后发现,是有一个坐标轴(虽然题目说了但没仔细看),起始从0,一共有L+1棵树,创建L+1大小的列表,使其数值全为1,接着遍历M,接收区域值,并使这些区域在列表上对应下标的数值变为0(就是移走的意思),最后求和列表,就知道有多少颗树未被移走。
L,M = map(int,input().split())
li=[]
for i in range(0,L+1):
li.append(1)
for i in range (M):
a,b=map(int,input().split())
for k in range(a-1,b):#第a颗树在列表中下标为a-1,第b颗树在列表中下标为b-1
li[k]=0#直接使其变为0
print(sum(li))