动态编程练习

时间:2015-04-06 22:43:52

标签: algorithm dynamic dynamic-programming

我一直在努力进行动态编程练习,而我似乎无法掌握它。我会在这里写下问题以及它的解决方案,明确说明我不理解的内容。

我们获得2个序列u1,u2,...,und1,d2,...,dm以及由正整数n x m构建的维度C=[cij]矩阵。 k对列表  据说((ui1, dj1),(ui2,dj2),...,(uik,djk))是非交叉的 i1 < 12 <..< ikj1 < j2 <...< jk。 &#34;列表的兼容性&#34;被认为是由它组成的对的总和的兼容性,即Ci1j1 + Ci2j2 + ... + Cikjk

示例: 考虑矩阵C = [Cij],所以Cij = squared(i + j)。让我成为 i = 1, 2, 3, j = 1, 2, 3, 4k = 2。一些包含2个非交叉对的列表是这些((u1, d2),(u3, d3)),兼容性为9 + 36 = 45((u2, d2),(u3, d4)),兼容性16 + 49 = 65,((u1, d1),(u2, d4)),,兼容性为4 + 36 = 40。一些非交叉的列表如下:((u2, d2),(u3, d1)),((u1, d4),(u3, d3)),((u3, d2),(u2, d3))

解决方案:

M(i,j,t)=取自ui,...,un和dj,... dm的非交叉对的最大成本

递推方程:
M(i, j, t) = max {M(i + 1, j + 1, t − 1) + c(i, j), M(i, j + 1, t),M(i + 1, j, t).}

  • M(i, j, 0) = 0
  • M(i, j, t) = −∞, if t > min{n − i + 1, m − j + 1}
  • M(i, j, t) = 0, if i > n or j > m

我没有很好地解决这个问题,为什么我们在−∞时将M(i, j, t)分配给t > min{n − i + 1, m − j + 1},而i > nj > m时为0分配{{1}}

解决方案是M(1,1,k)。

1 个答案:

答案 0 :(得分:2)

M(i, j, t) = max {M(i + 1, j + 1, t − 1) + c(i, j), M(i, j + 1, t),M(i + 1, j, t).}
           = max
             {
                 M(i+1, j+1, t-1) + c(i, j), <- we know the maximum cost of t-1 
                                                non-intersecting pairs taken from
                                                i+1,...,n and j+1,...,m to which
                                                we prepend the pair (i, j).
                 M(i, j+1, t), <- keep it at t elements and don't prepend anything,
                                  and take the one containing elements from
                                  i,...,n and j+1,...,m
                 M(i+1, j, t) <- same, but take elements from i+1,...,n and j,...,m
             }

这涵盖了所有情况:要么我们在前面添加当前元素并将长度增加1,要么我们不增加长度并采取这种(缺乏)动作所需的最大值。你可能会问“但M(i+1,j+1,t)呢?这也是一种有效的可能性。”它是,但它由另外两个案例覆盖:M(i+1,j,t)将检查M(i+1,j+1,t)并在需要时返回它。你可以自己添加它来重复发生,这不会是错误的,只是多余的。

  

为什么在t&gt;时将-∞分配给M(i,j,t)? min {n - i + 1,m - j + 1}

因为在这种情况下你无法找到解决方案。在步骤i,您只能从第一个序列中选择n - i + 1个元素(因为您已经选择了i)。 j也是如此。如果t > min{n - i + 1, m - j + 1},那么您将无法从其中一个列表中选择所需数量的元素,并使用负无穷大标记该元素。

  

但是当我&gt;时为0 n或j>米

这只是为了处理超出范围的错误。我不确定他们为什么选择0,我会为此选择负无穷大,只是为了保持一致性,或者只是通过在实现中加入条件来完全避免它(如果i + 1 >= n然后忽略这个分支,虽然如果没有分支是有效的,你仍然需要返回0 / -infinity),但这并不重要。

如果您返回0并且答案是否定的,那么您将遇到问题。当然,对于你的问题,由于构建C的方式,我们不能有一个否定的解决方案(因为C包含数字的方块,总是>= 0)。因此,在第一种情况下,你可以使用0代替负无穷大。

练习:你能写一个类似的重复,但解决方案是由M(n, m, k)给出的吗?首先用文字定义,然后用数学方法定义。