动态编程以找到两个子集

时间:2016-09-17 18:10:12

标签: algorithm dynamic-programming computer-science

  

X,Y {1,...,100n} |X|=3n的{​​{1}}子集|Y|=7n。查找A的{​​{1}}子集和X B子集,以便:两者都不为空,Y|A|=|B|

  • 我们可以对sum a_i = sum b_i集合进行O(n^2)总和(最大值为\{1,...,100n\},即使此1+... +100n和{{1}不可能不包括所有数字)
  • 每个总和都有X红衣主教(设定大小)(来自上一个项目符号)
  • 我们可以有Y(布尔)表,其大小为O(n),其中行代表基数,列代表数字。因此\{0,1\}表示我们可以创建基数为O(n) X O(n^2)的子集,并且该集合的总和为1
  • 第一行/列当然很容易计算

现在基本上我需要迭代所有单元格并在每个单元格i中更新它们。因此,我们最终会得到j的总体时间复杂度。

我该怎么做?

我想我可以逐行迭代它;这意味着,如果我想要更新单元格O(n)(含义,一个大小为O(n^4)的集合T[i,j]),那么我可以查找一组大小i加上一些等于j的术语。

BUT!可能是我们已经在前一集中使用了这个术语(大小为i-1) - 问题!

1 个答案:

答案 0 :(得分:1)

你快到了。您的动态编程应包含另一个参数:

允许将DP[K,J,I]定义为总和为K的第一个I元素的大小为J的子集数。这种动态编程的想法是,对于集合中的每个元素i,我们检查两种情况 - 将其添加到我们的子集中而不添加它。

DP[0,0,i] = 1
DP[k,j,0] = 0
DP[k,j,i] = DP[k-1,j-S[i],i-1] or DP[k,j,i-1]