📌  相关文章
📜  计数将数组拆分为两个子集的方法,它们的总和等于 K

📅  最后修改于: 2021-09-22 10:36:49             🧑  作者: Mango

给定一个大小为N的数组A[]和一个整数diff ,任务是计算将数组分成两个子集(非空子集是可能的)的方法数量,使得它们的总和之间的差等于diff

例子:

朴素方法:解决问题的最简单方法是基于以下观察:

因此,任务被简化为找到具有给定总和的子集数量。
因此,解决这个问题最简单的方法是生成所有可能的子集并检查该子集是否具有所需的总和。

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

高效的方法:为了优化上述方法,思想是使用动态规划。初始化一个大小为N*Xdp[][]表,其中dp[i][C]存储子数组A[i…N-1]的子集数量,使得它们的总和等于C 。因此,递归是非常微不足道的,因为只有两种选择,即要么考虑子集中的i元素,要么不考虑。所以递归关系将是:

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to count the number of ways to divide
// the array into two subsets and such that the
// difference between their sums is equal to diff
int countSubset(int arr[], int n, int diff)
{
    // Store the sum of the set S1
    int sum = 0;
    for (int i = 0; i < n; i++)
        sum += arr[i];
    sum += diff;
    sum = sum / 2;
 
    // Initializing the matrix
    int t[n + 1][sum + 1];
 
    // Number of ways to get sum
    // using 0 elements is 0
    for (int j = 0; j <= sum; j++)
        t[0][j] = 0;
 
    // Number of ways to get sum 0
    // using i elements is 1
    for (int i = 0; i <= n; i++)
        t[i][0] = 1;
 
    // Traverse the 2D array
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= sum; j++) {
 
            // If the value is greater
            // than the sum store the
            // value of previous state
            if (arr[i - 1] > j)
                t[i][j] = t[i - 1][j];
 
            else {
                t[i][j] = t[i - 1][j]
                          + t[i - 1][j - arr[i - 1]];
            }
        }
    }
 
    // Return the result
    return t[n][sum];
}
 
// Driver Code
int main()
{
    // Given Input
    int diff = 1, n = 4;
    int arr[] = { 1, 1, 2, 3 };
 
    // Function Call
    cout << countSubset(arr, n, diff);
}


Java
// Java program for the above approach
import java.io.*;
public class GFG
{
 
    // Function to count the number of ways to divide
    // the array into two subsets and such that the
    // difference between their sums is equal to diff
    static int countSubset(int []arr, int n, int diff)
    {
       
        // Store the sum of the set S1
        int sum = 0;
        for (int i = 0; i < n; i++)
            sum += arr[i];
        sum += diff;
        sum = sum / 2;
     
        // Initializing the matrix
        int t[][] = new int[n + 1][sum + 1];
     
        // Number of ways to get sum
        // using 0 elements is 0
        for (int j = 0; j <= sum; j++)
            t[0][j] = 0;
     
        // Number of ways to get sum 0
        // using i elements is 1
        for (int i = 0; i <= n; i++)
            t[i][0] = 1;
     
        // Traverse the 2D array
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= sum; j++) {
     
                // If the value is greater
                // than the sum store the
                // value of previous state
                if (arr[i - 1] > j)
                    t[i][j] = t[i - 1][j];
     
                else {
                    t[i][j] = t[i - 1][j]
                              + t[i - 1][j - arr[i - 1]];
                }
            }
        }
     
        // Return the result
        return t[n][sum];
    }
     
    // Driver Code
    public static void main(String[] args)
    {
         
        // Given Input
        int diff = 1, n = 4;
        int arr[] = { 1, 1, 2, 3 };
     
        // Function Call
        System.out.print(countSubset(arr, n, diff));
    }
}
 
// This code is contributed by AnkThon


Python3
# Python3 program for the above approach
 
# Function to count the number of ways to divide
# the array into two subsets and such that the
# difference between their sums is equal to diff
def countSubset(arr, n, diff):
     
    # Store the sum of the set S1
    sum = 0
    for i in range(n):
        sum += arr[i]
         
    sum += diff
    sum = sum // 2
 
    # Initializing the matrix
    t = [[0 for i in range(sum + 1)]
            for i in range(n + 1)]
 
    # Number of ways to get sum
    # using 0 elements is 0
    for j in range(sum + 1):
        t[0][j] = 0
 
    # Number of ways to get sum 0
    # using i elements is 1
    for i in range(n + 1):
        t[i][0] = 1
 
    # Traverse the 2D array
    for i in range(1, n + 1):
        for j in range(1, sum + 1):
             
            # If the value is greater
            # than the sum store the
            # value of previous state
            if (arr[i - 1] > j):
                t[i][j] = t[i - 1][j]
            else:
                t[i][j] = t[i - 1][j] + t[i - 1][j - arr[i - 1]]
 
    # Return the result
    return t[n][sum]
 
# Driver Code
if __name__ == '__main__':
     
    # Given Input
    diff, n = 1, 4
    arr = [ 1, 1, 2, 3 ]
 
    # Function Call
    print (countSubset(arr, n, diff))
 
# This code is contributed by mohit kumar 29


C#
// C# program for the above approach
 
using System;
 
public class GFG
{
 
    // Function to count the number of ways to divide
    // the array into two subsets and such that the
    // difference between their sums is equal to diff
    static int countSubset(int []arr, int n, int diff)
    {
       
        // Store the sum of the set S1
        int sum = 0;
        for (int i = 0; i < n; i++)
            sum += arr[i];
        sum += diff;
        sum = sum / 2;
     
        // Initializing the matrix
        int [,]t = new int[n + 1, sum + 1];
     
        // Number of ways to get sum
        // using 0 elements is 0
        for (int j = 0; j <= sum; j++)
            t[0,j] = 0;
     
        // Number of ways to get sum 0
        // using i elements is 1
        for (int i = 0; i <= n; i++)
            t[i,0] = 1;
     
        // Traverse the 2D array
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= sum; j++) {
     
                // If the value is greater
                // than the sum store the
                // value of previous state
                if (arr[i - 1] > j)
                    t[i,j] = t[i - 1,j];
     
                else {
                    t[i,j] = t[i - 1,j]
                              + t[i - 1,j - arr[i - 1]];
                }
            }
        }
     
        // Return the result
        return t[n,sum];
    }
     
    // Driver Code
    public static void Main(string[] args)
    {
         
        // Given Input
        int diff = 1, n = 4;
        int []arr = { 1, 1, 2, 3 };
     
        // Function Call
        Console.Write(countSubset(arr, n, diff));
    }
}
 
// This code is contributed by AnkThon


Javascript


输出:
3

时间复杂度: O(S*N),其中 S =数组元素总和+ K/2
辅助空间: O(S*N)

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