###思考题15-5
a)这个问题有点类似最长公共子序列,因此类似的定义
X
i
=
x
[
1
,
2...
i
]
,
Y
j
=
y
[
1
,
2...
j
]
X_i=x[1,2...i],Y_j=y[1,2...j]
Xi=x[1,2...i],Yj=y[1,2...j]。子问题就是确定一个最优操作序列使得
X
i
X_i
Xi 转换为
Y
j
Y_j
Yj,其中
0
≤
i
≤
m
,
0
≤
j
≤
n
0\le i\le m,0\le j\le n
0≤i≤m,0≤j≤n。原始的问题是
X
m
→
Y
n
X_m\rightarrow Y_n
Xm→Yn。
记
c
[
i
,
j
]
c[i,j]
c[i,j] 是
X
i
→
Y
j
X_i\rightarrow Y_j
Xi→Yj 的一个最优解决代价,然后有:
-
最后一步是复制操作,则必有 x [ i ] = y [ j ] x[i]=y[j] x[i]=y[j],子问题就变成 X i − 1 → Y j − 1 X_{i-1}\rightarrow Y_{j-1} Xi−1→Yj−1, X i → Y j X_i\rightarrow Y_j Xi→Yj 的最优解一定包括 X i − 1 → Y j − 1 X_{i-1}\rightarrow Y_{j-1} Xi−1→Yj−1 的最优解。因此有 c [ i , j ] = c [ i − 1 , j − 1 ] + c o s t ( c o p y ) c[i,j]=c[i-1,j-1]+cost(copy) c[i,j]=c[i−1,j−1]+cost(copy)。
-
最后一步是替换操作,则必有 x [ i ] ≠ y [ j ] x[i]\ne y[j] x[i]̸=y[j],同时假定替换操作不能替换成要被替换的字符本身,比如不能把字符 a a a 替换成字符 a a a。所以 c [ i , j ] = c [ i − 1 , j − 1 ] + c o s t ( r e p l a c e ) c[i,j]=c[i-1,j-1]+cost(replace) c[i,j]=c[i−1,j−1]+cost(replace)。
-
最后一步是旋转操作,则有 x [ i ] = y [ j − 1 ] , x [ i − 1 ] = y [ j ] x[i]=y[j-1],x[i-1]=y[j] x[i]=y[j−1],x[i−1]=y[j],同时也隐含了 i , j ≥ 2 i,j\ge 2 i,j≥2。子问题就变成了 X i − 2 → Y j − 2 X_{i-2}\rightarrow Y_{j-2} Xi−2→Yj−2,此时有 c [ i , j ] = c [ i − 2 , j − 2 ] + c o s t ( t w i d d l e ) c[i,j]=c[i-2,j-2]+cost(twiddle) c[i,j]=c[i−2,j−2]+cost(twiddle)。
-
最后一步是删除操作,对 x , y x,y x,y 没有限制,子问题就变成了 X i − 1 → Y j X_{i-1}\rightarrow Y_j Xi−1→Yj,得 c [ i , j ] = c [ i − 1 , j ] + c o s t ( d e l e t e ) c[i,j]=c[i-1,j]+cost(delete) c[i,j]=c[i−1,j]+cost(delete)。
-
最后一步是插入操作,对 x , y x,y x,y 没有限制。子问题就变成了 X i → Y j − 1 X_i\rightarrow Y_{j-1} Xi→Yj−1,得 c [ i , j ] = c [ i , j − 1 ] + c o s t ( i n s e r t ) c[i,j]=c[i,j-1]+cost(insert) c[i,j]=c[i,j−1]+cost(insert)。
-
最后一步是终止操作,我们必须完成 X m → Y n X_m\rightarrow Y_n Xm→Yn,也就是说必须是 i = m , j = n i=m,j=n i=m,j=n。终止操作可以看成是多次的删除操作,子问题变成 X i → Y n , 0 ≤ i < m X_i\rightarrow Y_n,0\le i<m Xi→Yn,0≤i<m。得 c [ m , n ] = min 0 ≤ i < m { c [ i , n ] + c o s t ( k i l l ) } c[m,n]=\min \limits_{0\le i<m}\{c[i,n]+cost(kill)\} c[m,n]=0≤i<mmin{c[i,n]+cost(kill)}。
最后来处理基本的情况,即 i = 0 i=0 i=0 或者 j = 0 j=0 j=0, X 0 , Y 0 X_0,Y_0 X0,Y0 都是空串,从 X 0 → Y j X_0\rightarrow Y_j X0→Yj 只需插入 j j j 次即可,所以 c [ 0 , j ] = j ⋅ c o s t [ i n s e r t ] c[0,j]=j·cost[insert] c[0,j]=j⋅cost[insert],类似的 X i → Y 0 X_i\rightarrow Y_0 Xi→Y0 只需删除 i i i 次即可, c [ i , 0 ] = i ⋅ c o s t [ d e l e t e ] c[i,0]=i·cost[delete] c[i,0]=i⋅cost[delete]。然后 c [ 0 , 0 ] = 0 c[0,0]=0 c[0,0]=0。
总结就是如下:
c
[
i
,
j
]
=
min
{
c
[
i
,
j
]
=
c
[
i
−
1
,
j
−
1
]
+
c
o
s
t
(
c
o
p
y
)
if x[i]=y[j]
c
[
i
,
j
]
=
c
[
i
−
1
,
j
−
1
]
+
c
o
s
t
(
r
e
p
l
a
c
e
)
if x[i]!= y[j]
c
[
i
,
j
]
=
c
[
i
−
2
,
j
−
2
]
+
c
o
s
t
(
t
e
i
d
d
l
e
)
if i,j ≥ 2 and x[i]=y[j-1],x[i-1]=y[j]
c
[
i
,
j
]
=
c
[
i
−
1
,
j
]
+
c
o
s
t
(
d
e
l
e
t
e
)
c
[
i
,
j
]
=
c
[
i
,
j
−
1
]
+
c
o
s
t
(
i
n
s
e
r
t
)
c
[
m
,
n
]
=
min
0
≤
i
<
m
{
c
[
i
,
n
]
+
c
o
s
t
(
k
i
l
l
)
}
if i=m,j=n
c[i,j]=\min \begin{cases} c[i,j]=c[i-1,j-1]+cost(copy)& \text{if x[i]=y[j]}\\ c[i,j]=c[i-1,j-1]+cost(replace)& \text{if x[i]!= y[j]}\\ c[i,j]=c[i-2,j-2]+cost(teiddle)& \text{if i,j ≥ 2 and x[i]=y[j-1],x[i-1]=y[j]}\\ c[i,j]=c[i-1,j]+cost(delete)\\ c[i,j]=c[i,j-1]+cost(insert)\\ c[m,n]=\min \limits_{0\le i<m}\{c[i,n]+cost(kill)\} & \text{if i=m,j=n} \end{cases}
c[i,j]=min⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧c[i,j]=c[i−1,j−1]+cost(copy)c[i,j]=c[i−1,j−1]+cost(replace)c[i,j]=c[i−2,j−2]+cost(teiddle)c[i,j]=c[i−1,j]+cost(delete)c[i,j]=c[i,j−1]+cost(insert)c[m,n]=0≤i<mmin{c[i,n]+cost(kill)}if x[i]=y[j]if x[i]!= y[j]if i,j ≥ 2 and x[i]=y[j-1],x[i-1]=y[j]if i=m,j=n
类似 LCS,按行优先开始计算。
EDIT-DISTANCE(x, y,m, n)
let c[0...m, 0...n] and op[0...m, 0...n] be new arrays
for i = 0 to m
c[i, 0] = i·cost(delete)
op[i, 0] = DELETE
for j = 0 to n
c[0, j] = j cost(insert)
op[0, j] = INSERT
for i = 1 to m
for j = 1 to n
c[i, j] = ∞
if x[i] == y[j]
c[i, j] = c[i-1, j-1] + cost(copy)
op[i, j] = COPY
if x[i] ≠ y[j] and c[i-1, j-1] + cost(replace) < c[i, j]
c[i, j] = c[i-1, j-1] + cost(replace)
op[i, j] = REPLACE(by y[j])
if i≥ 2 and j≥ 2 and x[i] == y[j-1] and x[i-1] == y[j]
and c[i-2, j-2] + cost(twiddle) < c[i, j]
c[i, j] = c[i-2, j-2] + cost(twiddle)
op[i, j] = TWIDDLE
if c[i-1, j] + cost(delete) < c[i, j]
c[i, j] = c[i-1, j] + cost(delete)
op[i, j] = DELETE
if c[i, j-1] + cost(insert) < c[i, j]
c[i, j] = c[i, j-1] + cost(insert)
op[i, j] = INSERT(y[j])
for i = 0 to m - 1
if c[i, n] + cost(kill) < c[m, n]
c[m, n] = c[i, n] + cost(kill)
op[m, n] = KILL i
return c and op
时空复杂度都是 Θ ( m n ) \Theta(mn) Θ(mn),若要保存 KILL 操作,还需要保存 killed 操作的下标 i 来帮助我们重建最优操作序列。
OP-SEQUENCE(op, i, j)
if i == 0 and j == 0
return
if op[i, j] == COPY or op[i, j] == REPLACE
i' = i-1
j' = j-1
elseif op[i, j] == TWIDDLE
i' = i-2
j' = j-2
elseif op[i, j] == DELETE
i' = i-1
j' = j
elseif op[i, j] == INSERT // don’t care yet what character is inserted
i' = i
j' = j-1
else // must be KILL, and must have i = m and j = n
let op[i, j] == KILL k
i' = k
j' = j
OP-SEQUENCE(op, i', j')
print op[i, j]
b)只允许下面四种操作,其余两种操作禁止。
cost(copy) = -1 ;
cost(replace) = +1 ;
cost(delete) = +2 ;
cost(insert) = +2 ;
因此 DNA 对齐问题就转换为求最小化编辑距离代价的负数。
###思考题15-6
使用动态规划,令
c
[
x
]
c[x]
c[x] 表示员工
x
x
x 的交际评分,我们希望找出所有员工的子集
S
S
S 使得当
x
∈
S
且
p
a
r
e
n
t
[
x
]
∉
S
x\in S\ 且\ parent[x]\notin S
x∈S 且 parent[x]∈/S 时有最大的
∑
x
∈
S
c
[
x
]
\sum \limits_{x\in S}c[x]
x∈S∑c[x]。
令
M
(
x
)
M(x)
M(x) 表示以
x
x
x 为根节点的子树且
x
x
x 被邀请时的最大交际评分,
M
′
(
x
)
M'(x)
M′(x) 表示以
x
x
x 为根节点的子树且
x
x
x 不被邀请时的最大交际评分,然后得到:
M
(
x
)
=
c
[
x
]
+
∑
y
∈
(
p
a
r
e
n
t
[
y
]
=
x
)
M
′
(
y
)
M
′
(
x
)
=
∑
y
∈
(
p
a
r
e
n
t
[
y
]
=
x
)
max
{
M
(
y
)
,
M
′
(
y
)
}
M(x)=c[x]+\sum \limits_{y\in (parent[y]=x)}M'(y)\\M'(x)=\sum \limits_{y\in (parent[y]=x)}\max \{M(y),M'(y)\}
M(x)=c[x]+y∈(parent[y]=x)∑M′(y)M′(x)=y∈(parent[y]=x)∑max{M(y),M′(y)}
上面的第一个式子表示员工
x
x
x 的交际评分以及
x
x
x 的直接下属
y
y
y 不被邀请时以
y
y
y 为根节点的子树的交际评分;第二个式子表示从员工
x
x
x 的直接下属(不包括
x
x
x)中邀请以员工
y
y
y 为根节点的子树的交际评分的最大值。
solve(x)
M(x) = c[x]
M'(x) = 0
y = left-child[x]
while y ≠ NIL
do solve(y)
M(x) = M(x) + M'(y)
M'(x) = M'(x) + max{M(y),M'(y)}
y = right-child[y]
以公司主席开始调用solve
函数。接下来决定邀请人员名单。
invite(x)
if M(x) > M'(x)
then invite x to the party
for all grandchildren y of x
invite(y)
else
for all children y of x
invite(y)
最后的时间复杂度就是 O ( n ) O(n) O(n)。
###思考题15-7
略,提供一个链接,有兴趣的可以看一看这里写链接内容
###思考题15-8
a) 令当前被删除的是
A
[
i
,
j
]
A[i,j]
A[i,j],则第
i
+
1
i+1
i+1 行应该怎么删除像素呢?当
A
[
i
,
j
]
A[i,j]
A[i,j] 处于列边界时(
i
=
1
或
者
i
=
n
i=1或者i=n
i=1或者i=n),比如
i
=
1
i=1
i=1,此时只有两种选择
A
[
i
+
1
,
j
]
A[i+1,j]
A[i+1,j] 和
A
[
i
+
1
,
j
+
1
]
A[i+1,j+1]
A[i+1,j+1]。其他情况下都可以有三种删除像素的选择:
A
[
i
+
1
,
j
−
1
]
,
A
[
i
+
1
,
j
]
,
A
[
i
+
1
,
j
+
1
]
A[i+1,j-1],A[i+1,j],A[i+1,j+1]
A[i+1,j−1],A[i+1,j],A[i+1,j+1]。也就是说对某一行的像素
p
p
p 来说,下一行的选择至少有两种。令
T
(
i
)
T(i)
T(i) 表示从第
1
1
1 行到第
i
i
i 行可能的接缝数。当
i
=
1
i=1
i=1 时
T
(
1
)
=
n
T(1)=n
T(1)=n。当
i
>
n
i>n
i>n 时有:
T
(
i
)
≥
2
T
(
i
−
1
)
T(i)\ge 2T(i-1)
T(i)≥2T(i−1),很容易计算得
T
(
i
)
=
n
2
i
−
1
T(i)=n2^{i-1}
T(i)=n2i−1。因此
T
(
m
)
=
n
2
m
−
1
T(m)=n2^{m-1}
T(m)=n2m−1。
b) 令
d
i
s
r
[
i
,
j
]
disr[i,j]
disr[i,j] 为从
A
[
i
,
j
]
A[i,j]
A[i,j] 开始的所有接缝中选择出来的接缝破坏度之和最小的一条接缝的值。基础情况是
d
i
s
r
[
m
,
j
]
=
d
[
m
,
j
]
,
j
=
1
,
2...
n
disr[m,j]=d[m,j],j=1,2...n
disr[m,j]=d[m,j],j=1,2...n,递归情况下有:
d
i
s
r
[
i
,
j
]
=
d
[
i
,
j
]
+
min
k
∈
K
{
d
i
s
r
[
i
+
i
,
j
+
k
]
}
disr[i,j]=d[i,j]+\min \limits_{k\in K}\{disr[i+i,j+k]\}
disr[i,j]=d[i,j]+k∈Kmin{disr[i+i,j+k]},
K
K
K 的取值如下:
K
=
{
{
0
,
1
}
if j=1
{
−
1
,
0
,
1
}
if 1<j<m
{
−
1
,
0
}
if j=m
K= \begin{cases} \{0,1\}& \text{if j=1}\\ \{-1,0,1\}& \text{if 1<j<m}\\ \{-1,0\}& \text{if j=m} \end{cases}
K=⎩⎪⎨⎪⎧{0,1}{−1,0,1}{−1,0}if j=1if 1<j<mif j=m
因此我们只用得到最小化的
d
i
s
r
[
1
,
j
]
disr[1,j]
disr[1,j] 即可。
COMPRESS-IMAGE(d)
m = d.rows
n = d.columns
let disr[1..m, 1..n] and next[1..m, 1..n] be new tables
for j = 1 to n
disr[m, j] = d[m, j]
for i = m - 1 downto 1
for j = 1 to n
low = max(-1, 1-j)
high = min(1, n-j)
disr[i, j] = ∞
for k = low to high
if disr[i + 1, j + k] < disr[i, j]
disr[i, j] = disr[i + 1, j + k]
next[i, j] = j + k
disr[i, j] = disr[i, j] + d[i, j]
val = ∞
start = 1
for j = 1 to n
if disr[1, j] < val
val = disr[1, j]
start = j
print “The minimum value of the disruptive measure is ” val
for i = 1 to m
print “cut point at ” (i, start)
start = next[i, start]
最后时间和空间复杂度都是 O ( m n ) O(mn) O(mn)。