此问题的最佳算法是什么?

时间:2019-03-17 16:27:14

标签: algorithm recursion

考虑集合A = a1,a2,...。 。 。 ,an-1,n个项目中的an,其中每个ai是一个正整数,而值Z作为以下问题的输入: 是否有子集A0 = {ai1,ai2,.. 。 。 ,aik}⊆这样 Z =✷ai1✷ai2✷。 。 。 ik aik,其中✷是+或-?。

例如,如果给定输入为{3,5,4}且Z = 2,则我们可以有2 = -3 + 5。而对于Z = 10,我们没有任何组合。对于Z = 6,我们有6 = -3 + 5 + 4的组合。

编写一个递归函数IsSummable(Z,A),以确定是否可以找到

子集A0⊆A,使得值Z可以通过元素的组合来实现 A0仅使用两个操作+或-。

1 个答案:

答案 0 :(得分:0)

这是子集总和的一种变体,可以使用动态规划在伪多项式时间内求解

这里的O(n * W)解决方案:其中w是abs(a [i])的总和

  1. 让我们说dp[i][j] = 1,如果我们在考虑i个项目后就可以得到j的总和,否则可以说是0。
  2. 基本情况:dp[0][0] = 1
  3. 另一种情况,当考虑元素i时,可以说其值为a [i]:
    • 我们可以从状态达到某些状态dp [i] [j]:
      • dp[i-1][j](跳过当前元素)
      • dp[i-1][j-a](带+号的当前元素)
      • dp[i-1][j+a](带有-符号的当前元素)

因此解决方案如下:

dp[0][0]=1

for(int i=1; i<=n; i++)
for(int j=-W; j<=W; j++)
dp[i][j]|=dp[i-1][j] | dp[i-1][j-a[i]] | dp[i-1][j+a[i]]

return dp[n][Z]