给定一组非负整数和一个值和,确定给定集合中是否有和等于给定和的子集。
例如:
set = {1,2,5,7}
sum = 8
=> true
我实际上用这段代码解决了问题:
public boolean isSubsetSum(int[] set, int sum) {
Arrays.sort(set);
boolean[][] memo = new boolean[set.length+1][sum+1];
for (int i = 0; i < memo.length; i++) {
memo[i][0] = true;
}
for (int i = 1; i < memo.length; i++) {
for (int j = 1; j < memo[i].length; j++) {
if (set[i-1] > j) {
memo[i][j] = memo[i-1][j];
} else {
memo[i][j] = memo[i-1][j] || memo[i-1][j-set[i-1]];
}
}
}
return memo[memo.length-1][memo[memo.length-1].length-1];
}
然而,现在我想重建所有可能的组合,形成给定的总和。
是可以从我的回忆录矩阵中做到这一点,还是我必须以不同的方式做到这一点?
创建一个名为take[i][j]
的新DP表,它是布尔值。如果将i-th
元素作为子集和j
,则为真。您可以将其与普通备忘表同时填写:
for (int i = 1; i < memo.length; i++) {
for (int j = 1; j < memo[i].length; j++) {
if (memo[i-1][j]){
//no need to take ith elements, first i-1 have sum j
take[i][j] = false;
memo[i][j] = true;
}
else if (j-set[i-1] >= 0 && memo[i-1][j-set[i-1]]){
//take ith element, and search for set of size j-set[i-1] in 1..i-1
take[i][j] = true;
memo[i][j] = true;
}
else{
//neither memo[i-1][j] or memo[i-1][j-set[i-1]] valid, so no way to make sum
take[i][j]=false;
memo[i][j]=false;
}
}
}
最后,要重新构建解决方案,请从以下内容开始:
int i =set.length
int j = sum
while (i>=0 && j>=0){
if (take[i][j]){
print(set[i])
j = j - set[i]
i=i-1
}
else{
i=i-1
}
}
您可以将其推广到所有解决方案集。
我有一个子集问题的工作代码,如果它发现一个子集等于所需的目标,它可以打印数字。 > 我想打印给定目标的所有可能的子集,我不知道要为此更改什么。 我如何让它对负数起作用?
我无法弄清楚重叠子问题的DP第一属性在哪里适合子集和问题。然而,我理解最优子结构部分。在执行包含和排除元素的递归解决方案时,问题在哪里重叠 是不是因为这是一个NP问题,所以没有DP的两个性质 问题的链接是http://www.geeksforgeeks.org/dynamic-programming-subset-sum-problem/ 有人能帮助我理解这一点吗。
问题链接如下: https://www.geeksforgeeks.org/dynamic-programming-subset-sum-problem/ 我没有看到重叠的子问题属性在问题中得到满足,至少在输入情况下是如此。例如,在下面的链接中,递归树没有任何重叠的子问题 http://www.zrzahid.com/subset-sum-problem-dynamic-programming/
我正在练习动态编程,我正在努力调试我的代码。这个想法是在给定一组数字的情况下找出求和是否可能。这是我的代码: 以下是输出: 据我所知,在我的fe语句中,算法应该向上1行,然后查看x和y的差异并检查该槽是否可能。例如,在最明显的情况下,最后一行的最后一个元素。那将是10(y)-11(x),它应该一直回到它上面一行的索引1,我们知道这是True。不完全确定我做错了什么,如果能帮助理解这一点,将不胜感激
给定一个数组,是否可以从起始索引开始选择一组整数,这样该组就与给定的目标相加?但是,附加的限制是必须选择所有的6。 groupSum6(0,[5,6,2],8)true groupSum6(0,[5,6,2],9)false groupSum6(0,[5,6,2],7)false 只是想弄清楚我错在哪里。声明nums[start]==6的特殊情况是不是错误的方法?
我正在为动态编程编写一些复习材料。我需要提出如何划分子问题,计算出基本情况,并提出递归公式。 给定 n 个正整数 a1,a2,...,an、一个数字 k 和一个目标 W,我们希望选择一个子集 T,其总和恰好是 k 个元素,其总和最接近 W。每个元素只能选择一次。定义一个具有 3 个参数的子问题(即 C[x,y,z] = ...)。 我只处理过几个动态编程示例,从未处理过定义子问题时需要3个参数的示