算法导论学习-动态规划

动态规划-钢条切割

问题描述:给定一段长度为n英寸的钢条和价格表p_i(i = 1,2,…,n),求钢条切割方案,使得销售收益r_n最大。主义,如果长度为n英寸的钢条价格p_n足够大,最优解可能就是完全不需要切割。

自顶向下递归实现(Θ(2n))

CUT-ROD(p, n){
if n == 0
    return 0
q = -∞
for i = 1 to n
    q = max(q, p[i] + CUT-ROD(p, n-i))
return q
}

使用动态规划方法求解最有钢条切割问题

付出额外内存空间来节省计算时间

带备忘的自顶向下法(Θ(n2))

MEMOIZED-CUT-ROD(p, n){
let r[0...n] be a new array
for i = 0 to n
    r[i] = -∞
return MEMOIZED-CUT-ROD-AUX(p, n, r)
}

MEMOIZED-CUT-ROD-AUX(p, n, r){
if r[n] >= 0
    return r[n]
if n == 0
    q = 0
else q = -∞
    for i = 1 to n
        q = max(q, MEMOIZED-CUT-ROD-AUX(p, n-i, r))
r[n] = q
return q
}

自底向上法(Θ(n2))

BOTTOM-UP-CUT-ROD(p, n){
let r[0...n] be a new array
r[0] = 0
for j = 1 to n
    q = -∞
    for i = 1 to j
        q = max(q, p[i] + r[j-i])
    r[j] = q
return r[n]
}

重构解

EXTENDED-BOTTOM-UP-CUT-ROD(p, n){
let r[0...n] and s[0...n] be new arrays
r[0] = 0
for j = 1 to n
    q = -∞
    for i = 1 to j
        if q < p[i] + r[j-i]
            q = p[i] + r[j-i] 
           s[j] = i
    r[j] = q
return r[n]
}

PRINT-CUT-ROD-SOLUTION (p, n){
(r, s) = EXTENDED-BOTTOM-UP-CUT-ROD(p, n)
while n > 0
    print s[n]
    n = n-s[n]
}

动态规划-矩阵链乘法

问题描述

给定n个矩阵的链<A1,A2,...,An>,矩阵Ai的规模为pi-1xpi(1 <= i <= n),求完全括号化方案,是的计算成绩A1A2...An所需标量乘法次数最少。

一个递归求解方案

image.png

计算最优代价——时间:(Ω(n3)),空间:(Θ(n2))

MATRIX-CHAIN-PRDER (p){
n = p.length - 1
let m[n, n] and s[n, n] be new tables
for i = 1 to n
    m[i, i] = 0
for i= 2 to n
    for i = 1 to n-l+1
        j = i+l-1
        m[i, j]  = ∞
        for k = i to j-1
            q = m[i, k] + m[k+1 j] + p_i-1*p_k*p_j
            if q < m[i, j]
                m[i, j] = q
                s[i, j] = k
return m and s
}

构造最优解

PRINT-OPTIMAL-PARENS(s, i, j){
if i == j
    print "A"_i
else print "("
    PRINT-OPTIMAL-PARENS(s, i, s[i, j])
    PRINT-OPTIMAL-PARENS(s, s[i, j]+1, j)
    print ")"
}

动态规划-最长公共子序列

问题描述

给定两个序列X=<x1, x2, ... , xm>和Y==<y1, y2, ... , ym>,求X和Y长度最长的公共子序列。

一个递归解

image.png

计算LCS的长度

LCS-ENGTH (X, Y){
m = X.lenght
n = Y.lenght
let b[1...m, 1...n] and c[1...m, 1...n] be new tables
for i = 1 to m
  c[i, 0] = 0
for j = 0 to n
  c[0, j] = 0
for i = 1 to m
  for j = 1 to n
    if x_i == y_i
      c[i, j] = c[i-1, j-1] =1
      b[i, j] = "↖"
    elseif c[i-1, j] >= c[i, j-1]
      c[i, j ] = c[i-1, j]
      b[i, j] = "↑"
    else c[i, j] = c[i, j-1]
      b[i, j] = "←"
reutrn b and c
}

构造LCS

PRINT-LCS (b, X, i, j){
if i == 0 or j == 0
  return
if b[i, j] == "↖"
  PRINT-LCS (b, X, i-1, j-1)
elseif b[i, j] = "↖"
   PRINT-LCS (b, X, i-1, j)
esle b[i, j] = "←"
  PRINT-LCS (b, X, i, j-1)
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。