📌  相关文章
📜  计算将“+”和“-”放在数组元素前以获得总和K的方法

📅  最后修改于: 2021-09-17 16:02:16             🧑  作者: Mango

给定一个由N 个非负整数组成的数组A[]和一个整数K ,任务是找到“+”“-”运算符可以放在数组A[]元素前面的方式数量,例如数组的总和变为K

例子:

方法:该问题可以基于以下观察来解决:

  1. 将在该元素前面具有‘+’ 和在该元素前面具有‘-‘的元素的总和存储在变量中,例如P1P2 ,这样数组的总和变为K
  2. 将数组A[] 的总和存储在一个变量中,比如K
  3. 因此,出现以下等式:
    1. P1 + P2 = 总和
    2. P1 – P2 = K
  4. 求解上述方程得到P1 = (sum + K) / 2
  5. 因此,问题已转化为求总和为 P1 的子集数。
  6. 如果A的元素等于0 ,则‘+’‘-‘运算符都在有效排列中工作,因此,可以安全地忽略0并单独计算。

因此,可以使用动态规划解决该问题。请按照以下步骤解决问题:

  1. 计算和存储阵列A []0的在A []中分别变量c的和的数目的元素的总和。
  2. 如果K大于sum(sum + K)是奇数,则返回0
  3. Ksum 相加并除以2,sum = (sum + K) / 2 ,这是所需的总和。找到等于该总和的子集数。
  4. 创建一个维度为N*sum的二维dp数组。其中dp[i][j]表示最多为i-1 且总和为j的子集数。
  5. 需要考虑的基本情况如下:
    1. dp[0][i] = 0 ,对于0 <= i <= sum ,因为没有考虑数组A[] 中的元素
    2. dp[i][0] = 1 ,对于0 <= i <= N ,因为总和0总是可能的。
  6. 1N迭代,并对每个当前索引i执行以下操作:
    1. 1迭代到sum并对每个当前索引j执行以下转换:
      1. 如果A[i – 1]小于jA[i – 1]不等于0 ,则设置dp[i][j] = dp[i – 1][j] + dp[i – 1][ j – A[i – 1]]。
      2. 否则,复制之前的状态,即dp[i][j] = dp[i – 1][j]。
  7. 最后,返回dp[N][sum]2 c (考虑 0)的乘积,dp[N][sum]*2 c

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to count number of ways
// '+' and '-' operators can be placed
// in front of array elements to make
// the sum of array elements equal to K
int solve(int A[], int N, int K)
{
    // Stores sum of the array
    int sum = 0;
 
    // Stores count of 0s in A[]
    int c = 0;
 
    // Traverse the array
    for (int i = 0; i < N; i++) {
 
        // Update sum
        sum += A[i];
 
        // Update count of 0s
        if (A[i] == 0)
            c++;
    }
    // Conditions where no arrangements
    // are possible which adds up to K
    if (K > sum || (sum + K) % 2)
        return 0;
 
    // Required sum
    sum = (sum + K) / 2;
 
    // Dp array
    int dp[N + 1][sum + 1];
    // Base cases
    for (int i = 0; i <= sum; i++)
        dp[0][i] = 0;
 
    for (int i = 0; i <= N; i++)
        dp[i][0] = 1;
 
    // Fill the dp array
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= sum; j++) {
 
            if (A[i - 1] <= j && A[i - 1])
                dp[i][j] = dp[i - 1][j]
                           + dp[i - 1][j - A[i - 1]];
            else
                dp[i][j] = dp[i - 1][j];
        }
    }
 
    // Return answer
    return dp[N][sum] + pow(2, c);
}
 
// Driver Code
int main()
{
    // Input
    int A[] = { 1, 1, 2, 3 };
    int N = sizeof(A) / sizeof(A[0]);
    int K = 3;
 
    // Function call
    cout << solve(A, N, K) << endl;
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Function to count number of ways
// '+' and '-' operators can be placed
// in front of array elements to make
// the sum of array elements equal to K
static int solve(int A[], int N, int K)
{
   
    // Stores sum of the array
    int sum = 0;
 
    // Stores count of 0s in A[]
    int c = 0;
 
    // Traverse the array
    for (int i = 0; i < N; i++) {
 
        // Update sum
        sum += A[i];
 
        // Update count of 0s
        if (A[i] == 0)
            c++;
    }
    // Conditions where no arrangements
    // are possible which adds up to K
    if ((K > sum) || (((sum + K) % 2) != 0))
        return 0;
 
    // Required sum
    sum = (sum + K) / 2;
 
    // Dp array
    int dp[][] = new int[N + 1][sum + 1];
    // Base cases
    for (int i = 0; i <= sum; i++)
        dp[0][i] = 0;
 
    for (int i = 0; i <= N; i++)
        dp[i][0] = 1;
 
    // Fill the dp array
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= sum; j++) {
 
            if ((A[i - 1] <= j)  && (A[i - 1] != 0))
                dp[i][j] = dp[i - 1][j]
                           + dp[i - 1][j - A[i - 1]];
            else
                dp[i][j] = dp[i - 1][j];
        }
    }
 
    // Return answer
    return dp[N][sum] + (int)Math.pow(2, c);
}
 
// Driver Code
public static void main(String[] args)
{
    // Input
    int A[] = { 1, 1, 2, 3 };
    int N = A.length;
    int K = 3;
 
    // Function call
    System.out.print(solve(A, N, K));
 
}
}
 
// This code is contributed by sanjoy_62.


Python3
# Python3 program for the above approach
 
# Function to count number of ways
# '+' and '-' operators can be placed
# in front of array elements to make
# the sum of array elements equal to K
def solve(A, N, K):
     
    # Stores sum of the array
    sum = 0
 
    # Stores count of 0s in A[]
    c = 0
 
    # Traverse the array
    for i in range(N):
         
        # Update sum
        sum += A[i]
 
        # Update count of 0s
        if (A[i] == 0):
            c += 1
 
    # Conditions where no arrangements
    # are possible which adds up to K
    if (K > sum or (sum + K) % 2):
        return 0
 
    # Required sum
    sum = (sum + K) // 2
 
    # Dp array
    dp = [[0 for i in range(sum + 1)]
             for j in range(N + 1)]
              
    # Base cases
    for i in range(sum + 1):
        dp[0][i] = 0
 
    for i in range(N + 1):
        dp[i][0] = 1
 
    # Fill the dp array
    for i in range(1, N + 1, 1):
        for j in range(1, sum + 1, 1):
            if (A[i - 1] <= j and A[i - 1]):
                dp[i][j] = (dp[i - 1][j] +
                            dp[i - 1][j - A[i - 1]])
            else:
                dp[i][j] = dp[i - 1][j]
 
    # Return answer
    return dp[N][sum] + pow(2, c)
 
# Driver Code
if __name__ == '__main__':
     
    # Input
    A = [ 1, 1, 2, 3 ]
    N = len(A)
    K = 3
 
    # Function call
    print(solve(A, N, K))
     
# This code is contributed by SURENDRA_GANGWAR


C#
// C# program for the above approach
using System;
 
public class GFG
{
 
  // Function to count number of ways
  // '+' and '-' operators can be placed
  // in front of array elements to make
  // the sum of array elements equal to K
  static int solve(int[] A, int N, int K)
  {
 
    // Stores sum of the array
    int sum = 0;
 
    // Stores count of 0s in A[]
    int c = 0;
 
    // Traverse the array
    for (int i = 0; i < N; i++) {
 
      // Update sum
      sum += A[i];
 
      // Update count of 0s
      if (A[i] == 0)
        c++;
    }
    // Conditions where no arrangements
    // are possible which adds up to K
    if ((K > sum) || (((sum + K) % 2) != 0))
      return 0;
 
    // Required sum
    sum = (sum + K) / 2;
 
    // Dp array
    int[, ] dp= new int[N + 1, sum + 1];
 
    // Base cases
    for (int i = 0; i <= sum; i++)
      dp[0, i] = 0;
 
    for (int i = 0; i <= N; i++)
      dp[i,0] = 1;
 
    // Fill the dp array
    for (int i = 1; i <= N; i++) {
      for (int j = 1; j <= sum; j++) {
 
        if ((A[i - 1] <= j)  && (A[i - 1] != 0))
          dp[i,j] = dp[i - 1,j]
          + dp[i - 1,j - A[i - 1]];
        else
          dp[i,j] = dp[i - 1,j];
      }
    }
 
    // Return answer
    return dp[N, sum] + (int)Math.Pow(2, c);
  }
 
  // Driver code
  static public void Main ()
  {
 
    // Input
    int[] A = { 1, 1, 2, 3 };
    int N = A.Length;
    int K = 3;
 
    // Function call
    Console.Write(solve(A, N, K));
  }
}
 
// This code is contributed by offbeat


Javascript


输出:
3

时间复杂度: O(N * sum)
辅助空间: O(N * sum)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程