子集和动态编程 - 重叠子问题

时间:2015-01-25 16:42:19

标签: algorithm recursion data-structures dynamic-programming

我无法弄清楚重叠子问题的DP优先属性在子集总和问题中的适用范围。但是,我理解最佳子结构部分。而包含和排除的递归解决方案是哪个元素重叠的问题?
是不是因为它是一个NP问题所以没有DP的两个属性。
问题的链接是http://www.geeksforgeeks.org/dynamic-programming-subset-sum-problem/
有人可以帮助我理解这个。

1 个答案:

答案 0 :(得分:2)

让我们调用整个数字集S = {s [1],....,s [n]},目标值k,如果有一个子集,则写入f(X,t)= 1总和为t的X,否则为0。所以我们想要计算的答案是f(S,k)。

只要两个不同的数字子集具有相同的总和,并且该总和小于目标k,您就会得到重叠的子问题。详细地,假设存在子集SI = {s [i_1],...,s [i_p]}和不同的子集SJ = {s [j_1],...,s [j_q]},使得总和(SI)=总和(SJ)< ķ。假设w.l.o.g.索引全部按顺序排列(即< b表示i_a< i_b和j_a< j_b),并且i_1< = j_1(如果不是,则只交换SI和SJ)。然后子问题f({s [1],...,s [m-1]},k-sum(SI))将出现(至少)通过调用树的两条不同路径:从f开始后( S,k)(即根)并选择包括SI中的所有数字,而不包括索引> = i_1的其他数字;并且在f(S,k)开始并且选择包括SJ中的所有数字而没有包含指数> = j_1的其他数字,然后选择也排除下一个j_1 - i_1数字。

工作示例

假设S = {3,4,5,6,11}且k = 14.那么通过排除11并包括5和6,我们得到子问题f({3,4},3) (这将有解决方案1) - 这对应于选择SI = {5,6}和i_1 = 3.或者,通过包括11然后排除5和6,我们再次到达子问题f({ 3,4},3) - 这对应于选择SJ = {11}和j_1 = 5。