动态规划表 - 找到破坏字符串的最小成本

Posted

技术标签:

【中文标题】动态规划表 - 找到破坏字符串的最小成本【英文标题】:Dynamic programming table - Finding the minimal cost to break a string 【发布时间】:2017-08-29 16:11:00 【问题描述】:

某种字符串处理语言提供原始操作 它将字符串分成两部分。由于该操作涉及 复制原始字符串,一个字符串需要 n 个单位的时间 长度 n,与切割位置无关。假设,现在, 你想把一个字符串分成很多块。

休息的顺序会影响总跑步次数 时间。例如,假设我们希望打破一个 20 个字符的字符串(例如 例如“abcdefghijklmnopqrst”)在索引 3、8 和 10 获取子字符串:“abcd”、“efghi”、“jk”和“lmnopqrst”。如果 休息按左右顺序进行,然后第一次休息花费 20 单位时间,第二次休息需要 16 个单位时间,第三次 中断需要 11 个时间单位,总共 47 个步骤。如果休息 按左右顺序进行,第一次休息需要 20 个单位的时间, 第二次休息需要 11 个单位时间,第三次休息需要 9 时间单位,总共只有 40 步。然而,最优 解是 38(切割的顺序是 10、3、8)。

输入是字符串的长度和一个带有剪切索引的升序数组。我需要设计一个动态规划表来找出断开字符串的最小成本以及执行切割的顺序。

我无法弄清楚表格结构的外观(某些单元格应该是某些子问题的答案,并且应该可以从其他条目等计算)。相反,我编写了一个递归函数来找到破坏字符串的最小成本:b0, b1, ..., bK 是必须对ij 之间的(子)字符串进行切割的索引。

totalCost(i, j, b0, b1, ..., bK) = j - i + 1 + min 
                                              totalCost(b0 + 1, j, b1, b2, ..., bK),
  totalCost(i, b1, b0                   ) + totalCost(b1 + 1, j, b2, b3, ..., bK),
  totalCost(i, b2, b0, b1               ) + totalCost(b2 + 1, j, b3, b4, ..., bK),
  ....................................................................................
  totalCost(i, bK, b0, b1, ..., b(k - 1))
 if k + 1 (the number of cuts) > 1,
j - i + 1 otherwise.

请帮我弄清楚表格的结构,谢谢!

【问题讨论】:

我已经使用递归函数解决了第一个问题,但实际上并不是我必须做的。 问题不清楚,你有n即字符串的长度,你想把它切成m个部分,你想确定要在哪些索引处切割? 我已经用一个更好的例子更新了帖子。 【参考方案1】:

例如,我们有一个长度为n = 20 的字符串,我们需要在cuts = [3, 8, 10] 的位置将其拆分。首先让我们在我们的数组中添加两个假削减:-1n - 1(以避免极端情况),现在我们有了cuts = [-1, 3, 8, 10, 19]。让我们填写表M,其中M[i, j] 是在i-th 和j-th 之间进行所有中断的最小时间单位。我们可以按规则填写:M[i, j] = (cuts[j] - cuts[i]) + min(M[i, k] + M[k, j]) where i < k < j。进行所有切割的最短时间将在单元格M[0, len(cuts) - 1] 中。 python中的完整代码:

# input
n = 20
cuts = [3, 8, 10]
# add fake cuts
cuts = [-1] + cuts + [n - 1]
cuts_num = len(cuts)
# init table with zeros
table = []
for i in range(cuts_num):
    table += [[0] * cuts_num]
# fill table
for diff in range(2, cuts_num):
    for start in range(0, cuts_num - diff):
        end = start + diff
        table[start][end] = 1e9
        for mid in range(start + 1, end):
            table[start][end] = min(table[start][end], table[
                                    start][mid] + table[mid][end])
        table[start][end] += cuts[end] - cuts[start]
# print result: 38
print(table[0][cuts_num - 1])

【讨论】:

以上是关于动态规划表 - 找到破坏字符串的最小成本的主要内容,如果未能解决你的问题,请参考以下文章

(动态规划)1547. 切棍子的最小成本(区间dp)/221. 最大正方形 / 1312. 让字符串成为回文串的最少插入次数(区间dp)

Leetcode 746. Min Cost Climbing Stairs 最小成本爬楼梯 (动态规划)

动态规划帮助:二叉树成本边

最小路径(动态规划)

使用动态规划求解最小分配

动态规划 最小编辑代价