输入:
N, the number of chars in a string
e[0..N-1]: (b,c) an element of set e[a] means [a,b) is a substring with score c.
(如果所有子字符串都是可能的,那么你可以只使用c(a,b)函数。)
例如,[1,2)表示覆盖字符串第二个字母的子字符串(半开区间)。
(空子字符串不允许;如果允许它们存在,那么只有在最多允许它们被“取”k次时才能正确处理它们)
输出:
s[i] is the score of the best substring covering of [0,i)
a[i]: [a[i],i) is the last substring used to cover [0,i); else NULL
算法 - 如果区间 e 不稀疏,则为 O(N^2);如果 e 是允许的区间总数,则为 O(N+E)。这实际上是在无环图中找到最佳路径:
for i = 0 to N:
a[i] <- NULL
s[i] <- 0
a[0] <- 0
for i = 0 to N-1
if a[i] != NULL
for (b,c) in e[i]:
sib <- s[i]+c
if sib>s[b]:
a[b] <- i
s[b] <- sib
为了得到成本为[c]的最佳覆盖三元组[a,b,c]:
i <- N
if (a[i]==NULL):
error "no covering"
while (a[i]!=0):
from <- a[i]
yield (from,i,s[i]-s[from]
i <- from
当然,你可以将(sib,c)存储在s[b]中并节省减法操作。