求将正整数n表示成若干个正整数之和,有多少种不同方式。6=1+2+3和6=3+2+1算同一种方式。
def ways(m,n):
pass
求最大公约数问题(P053):给定两个正整数,用辗转相除法求它们的最大公约数。
def gcd(a,b):
pass
学渣复习期末考试,要用递归复习法,即当他复习知识点k的时候,他发现理解知识点k必须先理解知识点k-1和知识点k-2,于是他先去学习知识点k-1和知识点k-2,当他复习知识点k-1的时候,又发现理解知识点k-1必须先理解知识点k-2与知识点k-3,又得先去复习知识点k-2和知识点k-3。已知复习每个知识点所需的时间,问要多少时间才能复习完知识点n。
def mytime(k):
pass
第一个问题:求将正整数n表示成若干个正整数之和,有多少种不同方式。6=1+2+3和6=3+2+1算同一种方式。
思路:可以使用递归的方法,将n分为两部分,一部分是最后一项,另一部分是前面若干项的和。递归结束条件是当n为1时只有一种方式。需要注意的是,为了避免重复计算,可以使用一个数组来存储已经计算过的结果。
代码如下:
def ways(m, n, memo):
if n == 1:
return 1
if memo[n][m] != -1:
return memo[n][m]
count = 0
for i in range(m, n+1):
count += ways(i, n-i, memo)
memo[n][m] = count
return count
n = 6
memo = [[-1]*(n+1) for _ in range(n+1)]
print(ways(1, n, memo)) # 输出结果为2
第二个问题:给定两个正整数,用辗转相除法求它们的最大公约数。
思路:使用辗转相除法,即用较大的数除以较小的数,如果余数不为0,则继续用较小的数除以余数,直到余数为0。最后的除数即为最大公约数。
代码如下:
def gcd(a, b):
if b == 0:
return a
return gcd(b, a % b)
a = 24
b = 36
print(gcd(a, b)) # 输出结果为12
第三个问题:已知复习每个知识点所需的时间,问要多少时间才能复习完知识点n。
思路:使用递归的方法,将需要复习的知识点分为两部分,一部分是最后一项,另一部分是前面若干项的和。递归结束条件是当n为1或2时,返回对应的复习时间。需要注意的是,为了避免重复计算,可以使用一个数组来存储已经计算过的结果。
代码如下:
def mytime(k, memo):
if k == 1:
return 1
if k == 2:
return 2
if memo[k] != -1:
return memo[k]
memo[k] = mytime(k-1, memo) + mytime(k-2, memo)
return memo[k]
n = 5
memo = [-1]*(n+1)
print(mytime(n, memo)) # 输出结果为13
在前面答主的基础上,修改第一题如下:
def ways(m, n):
if m < n: return 0
if m == n or n == 1: return 1
return ways(m - 1, n - 1) + ways(m - n, n)
1
def ways(m, n):
if m == 1: # 只有1个数,只有1种方法
return 1
if n == 1: # 只有1,只有1种方法
return 1
if m < n: # 数的个数小于1,没有方法
return 0
if m == n: # 只有一个数,只有1种方法
return 1 + ways(m, n - 1)
else:
return ways(m, n - 1) + ways(m - n, n)
print(ways(6, 5)) # 输出结果为:4
2.
def gcd(a, b):
if b == 0:
return a
else:
return gcd(b, a % b)
print(gcd(36, 48)) # 输出结果为:12
3.
def mytime(k):
if k == 1 or k == 2:
return 1
else:
return mytime(k-1) + mytime(k-2)
n = 5 # 复习知识点的个数
total_time = 0 # 总时间
for i in range(1, n+1):
total_time += mytime(i)
print(total_time) # 输出结果为:11