我正在学习子集和问题,我想在这里问一些问题
我刚才读到了这个链接中的C代码,我想知道为什么作者可以定义?
S[i,0]=true ,S[0,j]=false
S[i,0]
表示subset[1,...i]
总和为0
,为什么它可以分配给true
。?如果要打印内容,我该如何修改此算法?子集?
因为似乎禁止私下与作者聊天,所以我必须发布它。
(2)如果数组中有负数,我试图测试它是否合适。我如何定义S[i,0]
和S[0,j]
的初始值?
有人可以帮我澄清一下吗?
提前致谢!
答案 0 :(得分:1)
建议的基本子句存在问题,因为有了它,您也可以将s[n,0]
作为初始值。
subset-sum的递归公式的更好的停止子句是s[i,xi] = true
。这个想法很简单,集合{x1,x2,...,xi}
包含一个总和为xi
的子集 - 它是子集{xi}
。递归将在稍后处理其余部分,如果有一个子集求和为0,它将找到它。
根据这种方法,基本条款是:
s[i,xi] = true (for each i)
s[0,j] = false (for each j)
递归公式为:
s[i,j] = s[i-1,j] OR s[i-1,j-xi]
要获取实际位于子集中的元素,您需要遵循使用动态编程构建的矩阵。 “跟随”矩阵所做的选择,并坚持产生真实的路径,直到找到“停止子句”(s == xi)
可以用以下方式递归描述:
getSubset(i,s):
if s[i-1,s]: //there is a solution without choosing xi
return getSubset(i-1, s)
if (xi == s): //true base clause
l <- new list
l.append(xi)
return l
if s[i -1, s-xi]: //there is a solution when choosing xi
l <- getSubset(i-1,s-xi)
l.append(xi)
return l
它类似于很多(确保你明白为什么):How to find which elements are in the bag, using Knapsack Algorithm [and not only the bag's value]?