子集和重叠子问题(动态编程)

时间:2017-12-31 11:14:27

标签: c++ dynamic-programming subset-sum

问题的链接如下:
https://www.geeksforgeeks.org/dynamic-programming-subset-sum-problem/
对于任何输入案例,我都没有看到重叠的子问题属性在问题中得到满足。 例如,在以下链接中,递归树没有任何重叠的子问题 http://www.zrzahid.com/subset-sum-problem-dynamic-programming/

此外,例如在以下程序中没有重叠的子问题。当没有重叠的子问题时,我不明白动态编程在这里有何帮助。请解释一下。

bool isSubsetSum(int set[],int n, int sum)
{
    if(sum==0)
return true;
if(n==0 || sum<0)
    return false;
return isSubsetSum(set,n-1,sum-set[n-1]) || isSubsetSum(set,n-1,sum);
}
int main()
{
  int set[] = {3, 34, 4, 12, 5, 2};
  int sum = 9;
  int n = sizeof(set)/sizeof(set[0]);
  if (isSubsetSum(set, n, sum) == true)
     printf("Found a subset with given sum");
  else
     printf("No subset with given sum");
  return 0;
}

1 个答案:

答案 0 :(得分:0)

以这种方式思考:

如果set []中的总和等于 sum ,则有2种不同的可能性:

  1. 最后一个元素(其索引为n-1)包含在总和中          - &GT;在这种情况下,其他n-1个元素总和为 sum - set [n-1]

  2. 最后一个元素(其索引为n-1)不包含在总和中          - &GT;在这种情况下,其他n-1个元素总和为 sum

  3. 声明中的OR:return isSubsetSum(set,n-1,sum-set[n-1]) || isSubsetSum(set,n-1,sum);以递归方式检查可能性1.和2.

    如果集合中的某些元素[]等于 sum ,则某些点的递归将达到 sum = 0;并且它将在最终递归级别返回true,这会将TRUE传播到原始调用(请记住:如果A或B中至少有一个为TRUE,则OR OR B返回TRUE。)

    否则你得到的案例总和不等于0而n等于0,这将传播FALSE。