切割字符串的动态编程练习


16

我一直在研究本书中的以下问题。

某种字符串处理语言提供了一种原始操作,该操作将字符串分成两部分。由于此操作涉及复制原始字符串,因此与剪切位置无关,长度为n的字符串要花费n个时间单位。现在,假设您要将一个字符串分成许多段。中断的顺序可能会影响总运行时间。例如,如果要在位置以切割20个字符的字符串和,然后在位置使第一切口即被的总成本,而这样做位置10首先具有更好的成本。10 3 20 + 17 = 37 20 + 10 = 30310320+17=3720+10=30

我需要一种动态编程算法,该算法可给出剪切,以找到将字符串剪切成片段的最低成本。m + 1mm+1

Answers:


10

基本思想是:尝试所有切割位置为第一选择,递归求解各个零件,增加成本并选择最小值。

在公式中:

mino(s,C)={|s|,|C|=1|s|+mincC[mino(s1,c,{cCc<c}) + mino(sc+1|s|,{C-CCC>C}] 其他

请注意,将备忘录应用于此递归实际上可以节省工作,因为切换任何连续应用的剪切对的顺序都会导致解决相同的三个子问题。


1

首先找到一个递归算法,然后将其转换为表,这始终是一个好主意。

  1. FCñ
  2.    if(C =)返回0;
  3.   其他
  4.      opt =无穷大;
  5.     每个做cC
  6.       D={dC:d<c}
  7.       E={ec:eD,e>c}
  8.       opt=min{opt,f(D,c)+f(E,nc)}
  9.     返回 ;opt+n

因此,您可能会问:表中是否没有太多的C子集?观察到仅需要“连续”子集。并且只有个。(为什么?)另一个问题是:有些条目会更改值。我们可以通过在每个指定开始和结束位置来解决此问题,而不仅仅是指定长度。(n2)Ef


0

这与多集上的Quicksort非常相似;当切点最接近中间位置,然后我们递归时,它是最佳选择。

如果我给您改组的多重集M = {1,1,1..1,2,2 ... 2,....,m,m..m},则行程在每个切割点结束,您可以通过选择最靠近中间的切割作为枢轴来对其进行快速排序。将元素拆分为左右分区的操作与字符串拆分的方式一样,需要进行n次操作,因此您可以使用与Quicksort相同的参数来显示中位数是最佳的。 sk

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.