📌  相关文章
📜  将一个集合分成两个子集,使得子集和的差异最小

📅  最后修改于: 2021-09-17 07:41:08             🧑  作者: Mango

给定一组整数,任务是将其分成两组 S1 和 S2,使得它们和之间的绝对差最小。
如果有一个包含 n 个元素的集合 S,那么如果我们假设 Subset1 有 m 个元素,那么 Subset2 必须有 nm 个元素,并且 abs(sum(Subset1) – sum(Subset2)) 的值应该是最小的。

例子:

Input:  arr[] = {1, 6, 11, 5} 
Output: 1
Explanation:
Subset1 = {1, 5, 6}, sum of Subset1 = 12 
Subset2 = {11}, sum of Subset2 = 11        

这个问题主要是对动态规划的扩展|设置 18(分区问题)。
递归解
递归方法是从数组的所有值中生成所有可能的总和,并检查哪个解决方案是最佳解决方案。
为了生成和,我们要么将第 i 个项目包含在集合 1 中,要么不包含,即包含在集合 2 中。

C++
// A Recursive C++ program to solve minimum sum partition
// problem.
#include 
using namespace std;
  
// Function to find the minimum sum
int findMinRec(int arr[], int i, int sumCalculated,
               int sumTotal)
{
    // If we have reached last element.  Sum of one
    // subset is sumCalculated, sum of other subset is
    // sumTotal-sumCalculated.  Return absolute difference
    // of two sums.
    if (i == 0)
        return abs((sumTotal - sumCalculated)
                   - sumCalculated);
  
    // For every item arr[i], we have two choices
    // (1) We do not include it first set
    // (2) We include it in first set
    // We return minimum of two choices
    return min(
        findMinRec(arr, i - 1, sumCalculated + arr[i - 1],
                   sumTotal),
        findMinRec(arr, i - 1, sumCalculated, sumTotal));
}
  
// Returns minimum possible difference between sums
// of two subsets
int findMin(int arr[], int n)
{
    // Compute total sum of elements
    int sumTotal = 0;
    for (int i = 0; i < n; i++)
        sumTotal += arr[i];
  
    // Compute result using recursive function
    return findMinRec(arr, n, 0, sumTotal);
}
  
// Driver program to test above function
int main()
{
    int arr[] = { 3, 1, 4, 2, 2, 1 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << "The minimum difference between two sets is "
         << findMin(arr, n);
    return 0;
}


Java
// JAVA code to partition a set into two subsets
// such that the difference of subset sums
// is minimum
import java.util.*;
  
class GFG {
  
    // Function to find the minimum sum
    public static int findMinRec(int arr[], int i,
                                 int sumCalculated,
                                 int sumTotal)
    {
        // If we have reached last element.
        // Sum of one subset is sumCalculated,
        // sum of other subset is sumTotal-
        // sumCalculated.  Return absolute
        // difference of two sums.
        if (i == 0)
            return Math.abs((sumTotal - sumCalculated)
                            - sumCalculated);
  
        // For every item arr[i], we have two choices
        // (1) We do not include it first set
        // (2) We include it in first set
        // We return minimum of two choices
        return Math.min(
            findMinRec(arr, i - 1,
                       sumCalculated + arr[i - 1],
                       sumTotal),
            findMinRec(arr, i - 1, sumCalculated,
                       sumTotal));
    }
  
    // Returns minimum possible difference between
    // sums of two subsets
    public static int findMin(int arr[], int n)
    {
        // Compute total sum of elements
        int sumTotal = 0;
        for (int i = 0; i < n; i++)
            sumTotal += arr[i];
  
        // Compute result using recursive function
        return findMinRec(arr, n, 0, sumTotal);
    }
  
    /* Driver program to test above function */
    public static void main(String[] args)
    {
        int arr[] = { 3, 1, 4, 2, 2, 1 };
        int n = arr.length;
        System.out.print("The minimum difference"
                         + " between two sets is "
                         + findMin(arr, n));
    }
}
  
// This code is contributed by Arnav Kr. Mandal.


Python3
# Python3 program for the
# above approach
# A Recursive C program to
# solve minimum sum partition
# problem.
  
# Function to find the minimum sum
  
  
def findMinRec(arr, i, sumCalculated,
               sumTotal):
  
    # If we have reached last element.
    # Sum of one subset is sumCalculated,
    # sum of other subset is sumTotal-
    # sumCalculated.  Return absolute
    # difference of two sums.
    if (i == 0):
        return abs((sumTotal - sumCalculated) -
                   sumCalculated)
  
    # For every item arr[i], we have two choices
    # (1) We do not include it first set
    # (2) We include it in first set
    # We return minimum of two choices
    return min(findMinRec(arr, i - 1,
                          sumCalculated+arr[i - 1],
                          sumTotal),
               findMinRec(arr, i - 1,
                          sumCalculated, sumTotal))
  
# Returns minimum possible
# difference between sums
# of two subsets
  
  
def findMin(arr,  n):
  
    # Compute total sum
    # of elements
    sumTotal = 0
    for i in range(n):
        sumTotal += arr[i]
  
    # Compute result using
    # recursive function
    return findMinRec(arr, n,
                      0, sumTotal)
  
  
# Driver code
if __name__ == "__main__":
  
    arr = [3, 1, 4, 2, 2, 1]
    n = len(arr)
    print("The minimum difference " +
          "between two sets is ",
          findMin(arr, n))
  
# This code is contributed by Chitranayal


C#
// C# code to partition a set into two subsets
// such that the difference of subset sums
// is minimum
using System;
  
class GFG {
  
    // Function to find the minimum sum
    public static int findMinRec(int[] arr, int i,
                                 int sumCalculated,
                                 int sumTotal)
    {
        // If we have reached last element.
        // Sum of one subset is sumCalculated,
        // sum of other subset is sumTotal-
        // sumCalculated. Return absolute
        // difference of two sums.
        if (i == 0)
            return Math.Abs((sumTotal - sumCalculated)
                            - sumCalculated);
  
        // For every item arr[i], we have two choices
        // (1) We do not include it first set
        // (2) We include it in first set
        // We return minimum of two choices
        return Math.Min(
            findMinRec(arr, i - 1,
                       sumCalculated + arr[i - 1],
                       sumTotal),
            findMinRec(arr, i - 1, sumCalculated,
                       sumTotal));
    }
  
    // Returns minimum possible difference between
    // sums of two subsets
    public static int findMin(int[] arr, int n)
    {
  
        // Compute total sum of elements
        int sumTotal = 0;
        for (int i = 0; i < n; i++)
            sumTotal += arr[i];
  
        // Compute result using recursive function
        return findMinRec(arr, n, 0, sumTotal);
    }
  
    /* Driver program to test above function */
    public static void Main()
    {
        int[] arr = { 3, 1, 4, 2, 2, 1 };
        int n = arr.Length;
        Console.Write("The minimum difference"
                      + " between two sets is "
                      + findMin(arr, n));
    }
}
  
// This code is contributed by nitin mittal.


Javascript


C++
// A Recursive C program to solve minimum sum partition
// problem.
#include 
using namespace std;
  
// Returns the minimum value of the difference of the two
// sets.
int findMin(int arr[], int n)
{
    // Calculate sum of all elements
    int sum = 0;
    for (int i = 0; i < n; i++)
        sum += arr[i];
  
    // Create an array to store results of subproblems
    bool dp[n + 1][sum + 1];
  
    // Initialize first column as true. 0 sum is possible
    // with all elements.
    for (int i = 0; i <= n; i++)
        dp[i][0] = true;
  
    // Initialize top row, except dp[0][0], as false. With
    // 0 elements, no other sum except 0 is possible
    for (int i = 1; i <= sum; i++)
        dp[0][i] = false;
  
    // Fill the partition table in bottom up manner
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= sum; j++) {
            // If i'th element is excluded
            dp[i][j] = dp[i - 1][j];
  
            // If i'th element is included
            if (arr[i - 1] <= j)
                dp[i][j] |= dp[i - 1][j - arr[i - 1]];
        }
    }
  
    // Initialize difference of two sums.
    int diff = INT_MAX;
  
    // Find the largest j such that dp[n][j]
    // is true where j loops from sum/2 t0 0
    for (int j = sum / 2; j >= 0; j--) {
        // Find the
        if (dp[n][j] == true) {
            diff = sum - 2 * j;
            break;
        }
    }
    return diff;
}
  
// Driver program to test above function
int main()
{
    int arr[] = { 3, 1, 4, 2, 2, 1 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << "The minimum difference between 2 sets is "
         << findMin(arr, n);
    return 0;
}


Java
// A Recursive java program to solve
// minimum sum partition problem.
import java.io.*;
  
class GFG {
    // Returns the minimum value of
    // the difference of the two sets.
    static int findMin(int arr[], int n)
    {
        // Calculate sum of all elements
        int sum = 0;
        for (int i = 0; i < n; i++)
            sum += arr[i];
  
        // Create an array to store
        // results of subproblems
        boolean dp[][] = new boolean[n + 1][sum + 1];
  
        // Initialize first column as true.
        // 0 sum is possible  with all elements.
        for (int i = 0; i <= n; i++)
            dp[i][0] = true;
  
        // Initialize top row, except dp[0][0],
        // as false. With 0 elements, no other
        // sum except 0 is possible
        for (int i = 1; i <= sum; i++)
            dp[0][i] = false;
  
        // Fill the partition table
        // in bottom up manner
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= sum; j++) {
                // If i'th element is excluded
                dp[i][j] = dp[i - 1][j];
  
                // If i'th element is included
                if (arr[i - 1] <= j)
                    dp[i][j] |= dp[i - 1][j - arr[i - 1]];
            }
        }
  
        // Initialize difference of two sums.
        int diff = Integer.MAX_VALUE;
  
        // Find the largest j such that dp[n][j]
        // is true where j loops from sum/2 t0 0
        for (int j = sum / 2; j >= 0; j--) {
            // Find the
            if (dp[n][j] == true) {
                diff = sum - 2 * j;
                break;
            }
        }
        return diff;
    }
  
    // Driver program
    public static void main(String[] args)
    {
        int arr[] = { 3, 1, 4, 2, 2, 1 };
        int n = arr.length;
        System.out.println(
            "The minimum difference between 2 sets is "
            + findMin(arr, n));
    }
}
// This code is contributed by vt_m


Python3
# A Recursive Python3 program to solve
# minimum sum partition problem.
import sys
  
# Returns the minimum value of the
# difference of the two sets.
  
  
def findMin(a, n):
  
    su = 0
  
    # Calculate sum of all elements
    su = sum(a)
  
    # Create an 2d list to store
    # results of subproblems
    dp = [[0 for i in range(su + 1)]
          for j in range(n + 1)]
  
    # Initialize first column as true.
    # 0 sum is possible
    # with all elements.
    for i in range(n + 1):
        dp[i][0] = True
  
    # Initialize top row, except dp[0][0],
    # as false. With 0 elements, no other
    # sum except 0 is possible
    for j in range(1, su + 1):
        dp[0][j] = False
  
    # Fill the partition table in
    # bottom up manner
    for i in range(1, n + 1):
        for j in range(1, su + 1):
  
            # If i'th element is excluded
            dp[i][j] = dp[i - 1][j]
  
            # If i'th element is included
            if a[i - 1] <= j:
                dp[i][j] |= dp[i - 1][j - a[i - 1]]
  
    # Initialize difference
    # of two sums.
    diff = sys.maxsize
  
    # Find the largest j such that dp[n][j]
    # is true where j loops from sum/2 t0 0
    for j in range(su // 2, -1, -1):
        if dp[n][j] == True:
            diff = su - (2 * j)
            break
  
    return diff
  
  
# Driver code
a = [3, 1, 4, 2, 2, 1]
n = len(a)
  
print("The minimum difference between "
      "2 sets is ", findMin(a, n))
  
# This code is contributed by Tokir Manva


C#
// A Recursive C# program to solve
// minimum sum partition problem.
using System;
  
class GFG {
  
    // Returns the minimum value of
    // the difference of the two sets.
    static int findMin(int[] arr, int n)
    {
  
        // Calculate sum of all elements
        int sum = 0;
        for (int i = 0; i < n; i++)
            sum += arr[i];
  
        // Create an array to store
        // results of subproblems
        bool[, ] dp = new bool[n + 1, sum + 1];
  
        // Initialize first column as true.
        // 0 sum is possible  with all elements.
        for (int i = 0; i <= n; i++)
            dp[i, 0] = true;
  
        // Initialize top row, except dp[0,0],
        // as false. With 0 elements, no other
        // sum except 0 is possible
        for (int i = 1; i <= sum; i++)
            dp[0, i] = false;
  
        // Fill the partition table
        // in bottom up manner
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= sum; j++) {
  
                // If i'th element is excluded
                dp[i, j] = dp[i - 1, j];
  
                // If i'th element is included
                if (arr[i - 1] <= j)
                    dp[i, j] |= dp[i - 1, j - arr[i - 1]];
            }
        }
  
        // Initialize difference of two sums.
        int diff = int.MaxValue;
  
        // Find the largest j such that dp[n,j]
        // is true where j loops from sum/2 t0 0
        for (int j = sum / 2; j >= 0; j--) {
  
            // Find the
            if (dp[n, j] == true) {
                diff = sum - 2 * j;
                break;
            }
        }
        return diff;
    }
  
    // Driver code
    public static void Main(String[] args)
    {
        int[] arr = { 3, 1, 4, 2, 2, 1 };
        int n = arr.Length;
  
        Console.WriteLine("The minimum difference "
                          + "between 2 sets is "
                          + findMin(arr, n));
    }
}
  
// This code is contributed by Rajput-Ji


Javascript


C++
#include 
using namespace std;
  
int minDifference(int arr[], int n)
{
    int sum = 0;
    for (int i = 0; i < n; i++)
        sum += arr[i];
    int y = sum / 2 + 1;
    // dp[i] gives whether is it possible to get i as sum of
    // elements dd is helper variable
    // we use dd to ignoring duplicates
    bool dp[y], dd[y];
  
    // Initialising dp and dd
    for (int i = 0; i < y; i++) {
        dp[i] = dd[i] = false;
    }
  
    // sum = 0 is possible
    dd[0] = true;
    for (int i = 0; i < n; i++) {
        // updating dd[k] as true if k can be formed using
        // elements from 1 to i+1
        for (int j = 0; j + arr[i] < y; j++) {
            if (dp[j])
                dd[j + arr[i]] = true;
        }
        // updating dd
        for (int j = 0; j < y; j++) {
            if (dd[j])
                dp[j] = true;
            dd[j] = false; // reset dd
        }
    }
    // checking the number from sum/2 to 1 which is possible
    // to get as sum
  
    for (int i = y - 1; i >= 0; i--) {
        if (dp[i])
            return (sum - 2 * i);
        // since i is possible to form then another number
        // is sum-i
        // so mindifference is sum-i-i
    }
}
int main()
{
  
    int arr[] = { 1, 6, 11, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << "The Minimum difference of 2 sets is "
         << minDifference(arr, n) << '\n';
    return 0;
}


输出:

The minimum difference between two sets is 1

时间复杂度:

All the sums can be generated by either 
(1) including that element in set 1.
(2) without including that element in set 1.
So possible combinations are :-  
arr[0]      (1 or 2)  -> 2 values
arr[1]    (1 or 2)  -> 2 values
.
.
.
arr[n]     (2 or 2)  -> 2 values
So time complexity will be 2*2*..... *2 (For n times),
that is O(2^n).

动态规划
当元素的总和不太大时,可以使用动态规划来解决该问题。我们可以创建一个二维数组 dp[n+1][sum+1],其中 n 是给定集合中元素的数量,sum 是所有元素的总和。我们可以以自下而上的方式构建解决方案。

The task is to divide the set into two parts. 
We will consider the following factors for dividing it. 
Let 
  dp[n+1][sum+1] = {1 if some subset from 1st to i'th has a sum 
                      equal to j
                   0 otherwise}
    
    i ranges from {1..n}
    j ranges from {0..(sum of all elements)}  

So      
    dp[n+1][sum+1]  will be 1 if 
    1) The sum j is achieved including i'th item
    2) The sum j is achieved excluding i'th item.

Let sum of all the elements be S.  

To find Minimum sum difference, w have to find j such 
that Min{sum - j*2  : dp[n][j]  == 1 } 
    where j varies from 0 to sum/2

The idea is, sum of S1 is j and it should be closest
to sum/2, i.e., 2*j should be closest to sum.

下面是上面代码的实现。

C++

// A Recursive C program to solve minimum sum partition
// problem.
#include 
using namespace std;
  
// Returns the minimum value of the difference of the two
// sets.
int findMin(int arr[], int n)
{
    // Calculate sum of all elements
    int sum = 0;
    for (int i = 0; i < n; i++)
        sum += arr[i];
  
    // Create an array to store results of subproblems
    bool dp[n + 1][sum + 1];
  
    // Initialize first column as true. 0 sum is possible
    // with all elements.
    for (int i = 0; i <= n; i++)
        dp[i][0] = true;
  
    // Initialize top row, except dp[0][0], as false. With
    // 0 elements, no other sum except 0 is possible
    for (int i = 1; i <= sum; i++)
        dp[0][i] = false;
  
    // Fill the partition table in bottom up manner
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= sum; j++) {
            // If i'th element is excluded
            dp[i][j] = dp[i - 1][j];
  
            // If i'th element is included
            if (arr[i - 1] <= j)
                dp[i][j] |= dp[i - 1][j - arr[i - 1]];
        }
    }
  
    // Initialize difference of two sums.
    int diff = INT_MAX;
  
    // Find the largest j such that dp[n][j]
    // is true where j loops from sum/2 t0 0
    for (int j = sum / 2; j >= 0; j--) {
        // Find the
        if (dp[n][j] == true) {
            diff = sum - 2 * j;
            break;
        }
    }
    return diff;
}
  
// Driver program to test above function
int main()
{
    int arr[] = { 3, 1, 4, 2, 2, 1 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << "The minimum difference between 2 sets is "
         << findMin(arr, n);
    return 0;
}

Java

// A Recursive java program to solve
// minimum sum partition problem.
import java.io.*;
  
class GFG {
    // Returns the minimum value of
    // the difference of the two sets.
    static int findMin(int arr[], int n)
    {
        // Calculate sum of all elements
        int sum = 0;
        for (int i = 0; i < n; i++)
            sum += arr[i];
  
        // Create an array to store
        // results of subproblems
        boolean dp[][] = new boolean[n + 1][sum + 1];
  
        // Initialize first column as true.
        // 0 sum is possible  with all elements.
        for (int i = 0; i <= n; i++)
            dp[i][0] = true;
  
        // Initialize top row, except dp[0][0],
        // as false. With 0 elements, no other
        // sum except 0 is possible
        for (int i = 1; i <= sum; i++)
            dp[0][i] = false;
  
        // Fill the partition table
        // in bottom up manner
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= sum; j++) {
                // If i'th element is excluded
                dp[i][j] = dp[i - 1][j];
  
                // If i'th element is included
                if (arr[i - 1] <= j)
                    dp[i][j] |= dp[i - 1][j - arr[i - 1]];
            }
        }
  
        // Initialize difference of two sums.
        int diff = Integer.MAX_VALUE;
  
        // Find the largest j such that dp[n][j]
        // is true where j loops from sum/2 t0 0
        for (int j = sum / 2; j >= 0; j--) {
            // Find the
            if (dp[n][j] == true) {
                diff = sum - 2 * j;
                break;
            }
        }
        return diff;
    }
  
    // Driver program
    public static void main(String[] args)
    {
        int arr[] = { 3, 1, 4, 2, 2, 1 };
        int n = arr.length;
        System.out.println(
            "The minimum difference between 2 sets is "
            + findMin(arr, n));
    }
}
// This code is contributed by vt_m

蟒蛇3

# A Recursive Python3 program to solve
# minimum sum partition problem.
import sys
  
# Returns the minimum value of the
# difference of the two sets.
  
  
def findMin(a, n):
  
    su = 0
  
    # Calculate sum of all elements
    su = sum(a)
  
    # Create an 2d list to store
    # results of subproblems
    dp = [[0 for i in range(su + 1)]
          for j in range(n + 1)]
  
    # Initialize first column as true.
    # 0 sum is possible
    # with all elements.
    for i in range(n + 1):
        dp[i][0] = True
  
    # Initialize top row, except dp[0][0],
    # as false. With 0 elements, no other
    # sum except 0 is possible
    for j in range(1, su + 1):
        dp[0][j] = False
  
    # Fill the partition table in
    # bottom up manner
    for i in range(1, n + 1):
        for j in range(1, su + 1):
  
            # If i'th element is excluded
            dp[i][j] = dp[i - 1][j]
  
            # If i'th element is included
            if a[i - 1] <= j:
                dp[i][j] |= dp[i - 1][j - a[i - 1]]
  
    # Initialize difference
    # of two sums.
    diff = sys.maxsize
  
    # Find the largest j such that dp[n][j]
    # is true where j loops from sum/2 t0 0
    for j in range(su // 2, -1, -1):
        if dp[n][j] == True:
            diff = su - (2 * j)
            break
  
    return diff
  
  
# Driver code
a = [3, 1, 4, 2, 2, 1]
n = len(a)
  
print("The minimum difference between "
      "2 sets is ", findMin(a, n))
  
# This code is contributed by Tokir Manva

C#

// A Recursive C# program to solve
// minimum sum partition problem.
using System;
  
class GFG {
  
    // Returns the minimum value of
    // the difference of the two sets.
    static int findMin(int[] arr, int n)
    {
  
        // Calculate sum of all elements
        int sum = 0;
        for (int i = 0; i < n; i++)
            sum += arr[i];
  
        // Create an array to store
        // results of subproblems
        bool[, ] dp = new bool[n + 1, sum + 1];
  
        // Initialize first column as true.
        // 0 sum is possible  with all elements.
        for (int i = 0; i <= n; i++)
            dp[i, 0] = true;
  
        // Initialize top row, except dp[0,0],
        // as false. With 0 elements, no other
        // sum except 0 is possible
        for (int i = 1; i <= sum; i++)
            dp[0, i] = false;
  
        // Fill the partition table
        // in bottom up manner
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= sum; j++) {
  
                // If i'th element is excluded
                dp[i, j] = dp[i - 1, j];
  
                // If i'th element is included
                if (arr[i - 1] <= j)
                    dp[i, j] |= dp[i - 1, j - arr[i - 1]];
            }
        }
  
        // Initialize difference of two sums.
        int diff = int.MaxValue;
  
        // Find the largest j such that dp[n,j]
        // is true where j loops from sum/2 t0 0
        for (int j = sum / 2; j >= 0; j--) {
  
            // Find the
            if (dp[n, j] == true) {
                diff = sum - 2 * j;
                break;
            }
        }
        return diff;
    }
  
    // Driver code
    public static void Main(String[] args)
    {
        int[] arr = { 3, 1, 4, 2, 2, 1 };
        int n = arr.Length;
  
        Console.WriteLine("The minimum difference "
                          + "between 2 sets is "
                          + findMin(arr, n));
    }
}
  
// This code is contributed by Rajput-Ji

Javascript


输出:

The minimum difference between 2 sets is 1

时间复杂度= O(n*sum) 其中 n 是元素的数量,sum 是所有元素的总和。

空间复杂度较低的动态规划:

我们可以使用一维数组 dp[sum/2+1] 来解决这个问题,而不是使用二维数组。

假设集合 1 的元素总和是 x 而集合 2 的元素总和将是 sm-x(sm 是 arr 的所有元素的总和)。

所以我们必须最小化 abs(sm-2*x)。

因此,为了最小化两个集合之间的差异,我们需要知道一个小于 sum/2 的数字(sum 是数组中所有元素的总和),并且可以通过将数组中的元素相加来生成。

C++

#include 
using namespace std;
  
int minDifference(int arr[], int n)
{
    int sum = 0;
    for (int i = 0; i < n; i++)
        sum += arr[i];
    int y = sum / 2 + 1;
    // dp[i] gives whether is it possible to get i as sum of
    // elements dd is helper variable
    // we use dd to ignoring duplicates
    bool dp[y], dd[y];
  
    // Initialising dp and dd
    for (int i = 0; i < y; i++) {
        dp[i] = dd[i] = false;
    }
  
    // sum = 0 is possible
    dd[0] = true;
    for (int i = 0; i < n; i++) {
        // updating dd[k] as true if k can be formed using
        // elements from 1 to i+1
        for (int j = 0; j + arr[i] < y; j++) {
            if (dp[j])
                dd[j + arr[i]] = true;
        }
        // updating dd
        for (int j = 0; j < y; j++) {
            if (dd[j])
                dp[j] = true;
            dd[j] = false; // reset dd
        }
    }
    // checking the number from sum/2 to 1 which is possible
    // to get as sum
  
    for (int i = y - 1; i >= 0; i--) {
        if (dp[i])
            return (sum - 2 * i);
        // since i is possible to form then another number
        // is sum-i
        // so mindifference is sum-i-i
    }
}
int main()
{
  
    int arr[] = { 1, 6, 11, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << "The Minimum difference of 2 sets is "
         << minDifference(arr, n) << '\n';
    return 0;
}
输出
The Minimum difference of 2 sets is 1

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

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