算法导论(Python版本)(第15章)

1. 自顶向下递归实现动态规划(切钢条问题)

'''
p 表示对应长度的钢条价格
n表示可分割的总长度
'''
def CUT_ROD(p, n):
    if n == 0:
        return 0
    q = float('-inf')
    for i in range(n):
        q = max(q, p[i] + CUT_ROD(p, n-i-1))
    return q

p = [1,5,8,9,10,17,17,20,24,30]
for i in range(11):
    print(CUT_ROD(p, i))

2. 自底向上实现动态规划(切钢条问题)

'''
p 表示对应长度的钢条价格
n 表示可分割的总长度
'''

def BOTTOM_UP_CUT_ROD(p, n):
    r = [0]*(n+1)
    s = [0]*(n+1)
    r[0] = 0
    for j in range(1, n+1):
        q = float('-inf')
        for i in range(1, j+1):
            if q< p[i] + r[j-i]:
                q = p[i] + r[j - i]
                s[j] = i
        r[j] = q
    return r, s

p = [0, 1,5,8,9,10,17,17,20,24,30]

print(BOTTOM_UP_CUT_ROD(p, 10))

3. 矩阵链乘法问题

def MATRIX_CHAIN_ORDER(p):
    n = len(p) - 1
    m = [[float('inf') for i in range(1, n+1)] for j in range(1, n+1)]
    s = [[0 for i in range(1, n+2)] for j in range(2, n+3)]

    for i in range(n):
        m[i][i] = 0

    for l in range(2, n+1):   #链的长度 (从2到n-1)
        for i in range(1, n-l+2):
            j = i + l - 1
            for k in range(i, j):
                q = m[i-1][k-1] + m[k][j-1] + p[i-1] * p[k] * p[j]
                if q < m[i-1][j-1]:
                    m[i-1][j-1] = q
                    s[i-1][j-1] = k
    return m, s

p = [30,35,15,5,10,20,25]
print(MATRIX_CHAIN_ORDER(p))

4. 最长公共子序列问题LCS 

def LCS_length(X, Y):
    m = len(X)
    n = len(Y)

    c = [[0] * (n+1)] * (m+1)

    for i in range(m):
        for j in range(n):
            if X[i] == Y[j]:
                c[i][j] = c[i-1][j-1] + 1

            elif c[i-1][j] > c[i][j-1]:
                c[i][j] = c[i-1][j]
            else:
                c[i][j] = c[i][j-1]

    return c[m-1][n-1]

print(LCS_length(['A','B','C','B','D','A','B'],['B','D','C','A','B','A']))

 

你可能感兴趣的:(算法导论(Python版本)(第15章))