[Educoder Discrete Mathematics Training] Recursion in solving computer problems ※
Regarding recursion, in fact, simply speaking, it means calling yourself. To elaborate, it is divided into two parts: recursion and backtracking. It’s just that this training did not use backtracking in a real sense.
T1 Recursion based on recursion formula
As usual, let’s chat a little bit. This kind of recursion based on recursive formulas, dynamic programming, etc. is a tree structure, and its essence is traversal, and there is no need to be recursive. For a few questions after that, I didn’t write recursion, just loop directly.
#第一题
def power(a, n):
#********** Begin **********#
if n == 0 :
return 1
elif n == 1 :
return a
else :
return a * power(a, n - 1)
#********** End **********#
…
print('*' * 20)
for n in range(11):
print(fib2(n))
T2 Recursion without recursion formula
This question gives us an idea. Recursion is actually mathematical induction.
Essentially, recursion is thinking about the problem from the end point.
#第一题
def isPal(s):
# 请在下面编写代码
n = len(s)
if n == 0 or n == 1 :
return True
else :
if s[0] == s[-1] :
return isPal(s[1 : n - 1])
else :
… for n in range(6):
print(vonNeumann(n))
ALPHABET = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
for n in range(1,5):
print('*' * 20)
string = ALPHABET[:n]
print(perm(string))
T3 Recursion and Mathematical Induction
Note that the first two sortings require direct modification of the sequence, and my second sorting changes the output mode of the main function.
from random import *
#第一题
def findNomap(A, f):
for a in A:
mapped = False
for m in f:
if m[1] == a:
mapped = True
break
if mapped == False:
return a
return None
def mapping(A, f):
# 请在下面编写代码
#********** Begin **********#
n = len(A)
if n == 1 :
return A
else :
mdl = findNomap(A, f)
if mdl :
A.remove(mdl)
for x in f :
if x[0] == mdl or x[1] == mdl :
f.remove(x)
return mapping(A, f)
else :
return A
#********** End **********#
# 请不要修改下面的代码
#第二题
def InsertSort(seq, i):
# 请在下面编写代码
#********** Begin **********#
if i == 0 :
return
else :
i = i + 1
mdl = seq[:i - 1]
InsertSort(mdl, i - 2)
for j in range(i - 1) :
if mdl[j] > seq[i - 1] :
for k in range(j) :
seq[k] = mdl[k]
seq[j] = seq[i - 1]
for k in range(j, i - 1) :
seq[k + 1] = mdl[k]
return
for j in range(i - 1) :
seq[j] = mdl[j]
#********** End **********#
# 请不要修改下面的代码
#第三题
def SelectSort(seq, i):
# 请在下面编写代码
#********** Begin **********#
if i == 0 :
return seq
else :
# print(seq, i)
i = i + 1
mx, Id = seq[0], 0
for j in range(1, i) :
if seq[j] > mx :
mx, Id = seq[j], j
return SelectSort(seq[:Id] + seq[Id + 1:], i - 2) + [mx]
#********** End **********#
#请不要修改下面的代码
#第四题
def QuickSort(seq):
#请在下面编写代码
#********** Begin **********#
n = len(seq)
if n == 1 :
return seq
elif n == 0 :
return seq
else :
L1, L2 = [], []
for i in range(1, n) :
if seq[i] < seq[0] :
L1.append(seq[i])
else :
L2.append(seq[i])
return QuickSort(L1) + [seq[0]] + QuickSort(L2)
#********** End **********#
#请不要修改下面的代码
if __name__=="__main__":
f = [(1, 3), (2, 1), (3, 1), (4, 5), (5, 5), (6, 4), (7, 6)]
g = [(1, 3), (3, 1), (4, 5), (6, 4), (5, 7), (7, 6)]
h = [(1, 3), (3, 2), (4, 4), (6, 7), (2, 2), (7, 5)]
for l in [f, g, h]:
A = [1, 2, 3, 4, 5, 6, 7]
print(mapping(A, l))
print('*' * 20)
seed(999)
test = [[],[],[],[]]
for i in range(4):
for j in range(10):
test[i].append(randint(1,100))
for l in test:
InsertSort(l, len(l)-1)
print(l)
print('*' * 20)
seed(9999)
test1 = [[], [], [], []]
for i in range(4):
for j in range(10):
test1[i].append(randint(100, 1000))
for l in test1:
print(SelectSort(l, len(l) - 1))
print('*' * 20)
seed(99999)
test2 = [[], [], [], []]
for i in range(4):
for j in range(10):
test2[i].append(randint(10, 1000))
for l in test2:
print(QuickSort(l))
T4 Recursion and Dynamic Programming
There is really no need for recursion. If there are two questions, it can be directly looped.
As for that m e m o memo memo, the meaning lies in some positions will be recursed multiple times. For example, say a position c o s t i , j cost_{i,j} costi,j,Just need x ≥ i x\ge i x≥i且 y ≥ j y\ge j and≥j,nanao ( i , j ) (i,j) (i,j)This position will be recursed once. Very time consuming and pointless. Then we use a m e m o r y memory memory array, if this position Just save it after being recursed.
from random import *
from time import clock
#********** Begin **********#
#第一题
def minPathCost(cost, i, j):
# 请在下面编写代码
#********** Begin **********#
# if i == 0 and j == 0 :
# return cost[0][0]
# Min = 10**10
# if i > 0 :
# Min = min(Min, minPathCost(cost, i - 1, j))
# if j > 0 :
# Min = min(Min, minPathCost(cost, i, j - 1))
# Min += cost[i][j]
# return Min
f= []
for x in range(i + 1) :
mdl = [0] * (j + 1)
f.append(mdl)
for x in range(i + 1) :
for y in range(j + 1) :
if x == 0 and y == 0 :
f[x][y] = cost[x][y]
continue
f[x][y] = 10 ** 10
if x > 0 :
f[x][y] = min(f[x][y], f[x - 1][y])
if y > 0 :
f[x][y] = min(f[x][y], f[x][y - 1])
f[x][y] += cost[x][y]
return f[i][j]
#********** End **********#
# 请不要修改下面的代码
#第二题
def minPathCost_Memo(cost, i, j, memo):
# 请在下面编写代码
#********** Begin **********#
if memo[i][j] :
return memo[i][j]
if i == 0 and j == 0 :
memo[i][j] = cost[i][j]
return cost[0][0]
Min = 10**10
if i > 0 :
Min = min(Min, minPathCost(cost, i - 1, j))
if j > 0 :
Min = min(Min, minPathCost(cost, i, j - 1))
Min += cost[i][j]
memo[i][j] = Min
return Min
#********** End **********#
# 请不要修改下面的代码
#第三题
def countWays(n):
# 请在下面编写代码
#********** Begin **********#
if n == 1 :
return 1
elif n == 2 :
return 2
else :
return countWays(n - 1) + countWays(n - 2)
#********** End **********#
# 请不要修改下面的代码
#第四题
def countWays_Memo(n, memo={
}):
# 请在下面编写代码
f = [0] * (n + 2)
f[1], f[2] = 1, 2
for i in range(3, n + 1) :
f[i] = f[i - 1] + f[i - 2]
return f[n]
#********** End **********#
# 请不要修改下面的代码
#********** end **********#
if __name__=="__main__":
randseeds = [9, 99, 999, 9999, 99999]
for trial in range(5):
seed(randseeds[trial])
cost = []
for i in range(10):
temp = []
for j in range(10):
temp.append(randint(1,10))
cost.append(temp)
#start = clock()
print(minPathCost(cost, 9, 9))
#print(clock() - start)
print('*' * 20)
randseeds = [9, 99, 999, 9999, 99999]
for trial in range(5):
seed(randseeds[trial])
cost = []
for i in range(100):
temp = []
for j in range(100):
temp.append(randint(1, 10))
cost.append(temp)
memo = []
for i in range(100):
memo.append([0] * 100)
#start = clock()
print(minPathCost_Memo(cost, 99, 99, memo))
#print(clock()-start)
print('*' * 20)
for n in range(25,35):
print(countWays(n))
print('*' * 20)
for n in range(90,100):
print(countWays_Memo(n))