📌  相关文章
📜  给定数组表示S所需的最小数目的数字

📅  最后修改于: 2021-05-24 19:35:27             🧑  作者: Mango

给定一个整数S和一个数组arr [] ,任务是找到总和为S的最小元素数,以便可以选择任意次数数组中的任何元素以获得总和S。

例子:

方法:
想法是递归地找到每个可能的序列,以使它们的总和等于给定的S,并跟踪最小序列,以使它们的总和为S。这样,可以很容易地计算出最小的可能解。

下面是上述方法的实现:

C++
// C++ implementation to find the
// minimum number of sequence
// required from array such that
// their sum is equal to given S
 
#include 
using namespace std;
 
// Function to find the
// minimum elements required to
// get the sum of given value S
int printAllSubsetsRec(int arr[],
                    int n,
                    vector v,
                    int sum)
{
    // Condition if the
    // sequence is found
    if (sum == 0) {
        return (int)v.size();
    }
 
    if (sum < 0)
        return INT_MAX;
 
    // Condition when no
    // such sequence found
    if (n == 0)
        return INT_MAX;
 
    // Calling for without choosing
    // the current index value
    int x = printAllSubsetsRec(
        arr,
        n - 1, v, sum);
 
    // Calling for after choosing
    // the current index value
    v.push_back(arr[n - 1]);
    int y = printAllSubsetsRec(
        arr, n, v,
        sum - arr[n - 1]);
    return min(x, y);
}
 
// Function for every array
int printAllSubsets(int arr[],
                    int n, int sum)
{
    vector v;
    return printAllSubsetsRec(arr, n,
                            v, sum);
}
 
// Driver Code
int main()
{
    int arr[] = { 2, 1, 4, 3, 5, 6 };
    int sum = 6;
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << printAllSubsets(arr, n, sum)
        << endl;
    return 0;
}


Java
// Java implementation to find the
// minimum number of sequence
// required from array such that
// their sum is equal to given S
import java.util.*;
import java.lang.*;
 
class GFG{
     
// Function to find the
// minimum elements required to
// get the sum of given value S
static int printAllSubsetsRec(int arr[],
                              int n,
                              ArrayList v,
                              int sum)
{
     
    // Condition if the
    // sequence is found
    if (sum == 0)
    {
        return (int)v.size();
    }
  
    if (sum < 0)
        return Integer.MAX_VALUE;
         
    // Condition when no
    // such sequence found
    if (n == 0)
        return Integer.MAX_VALUE;
  
    // Calling for without choosing
    // the current index value
    int x = printAllSubsetsRec(
            arr,
            n - 1, v, sum);
  
    // Calling for after choosing
    // the current index value
    v.add(arr[n - 1]);
     
    int y = printAllSubsetsRec(
            arr, n, v,
            sum - arr[n - 1]);
    v.remove(v.size() - 1);
     
    return Math.min(x, y);
}
 
// Function for every array
static int printAllSubsets(int arr[],
                           int n, int sum)
{
    ArrayList v = new ArrayList<>();
    return printAllSubsetsRec(arr, n,
                              v, sum);
}
 
// Driver code
public static void main(String[] args)
{
    int arr[] = { 2, 1, 4, 3, 5, 6 };
    int sum = 6;
    int n = arr.length;
     
    System.out.println(printAllSubsets(arr, n, sum));
}
}
 
// This code is contributed by offbeat


Python3
# Python3 implementation to find the
# minimum number of sequence
# required from array such that
# their sum is equal to given S
import sys
 
# Function to find the
# minimum elements required to
# get the sum of given value S
def printAllSubsetsRec(arr, n, v, Sum):
     
    # Condition if the
    # sequence is found
    if (Sum == 0):
        return len(v)
 
    if (Sum < 0):
        return sys.maxsize
 
    # Condition when no
    # such sequence found
    if (n == 0):
        return sys.maxsize
 
    # Calling for without choosing
    # the current index value
    x = printAllSubsetsRec(arr, n - 1, v, Sum)
 
    # Calling for after choosing
    # the current index value
    v.append(arr[n - 1])
    y = printAllSubsetsRec(arr, n, v,
                           Sum - arr[n - 1])
    v.pop(len(v) - 1)
 
    return min(x, y)
 
# Function for every array
def printAllSubsets(arr, n, Sum):
     
    v = []
    return printAllSubsetsRec(arr, n, v, Sum)
     
# Driver code
arr = [ 2, 1, 4, 3, 5, 6 ]
Sum = 6
n = len(arr)
 
print(printAllSubsets(arr, n, Sum))
 
# This code is contributed by avanitrachhadiya2155


C#
// C# implementation to find the
// minimum number of sequence
// required from array such that
// their sum is equal to given S
using System;
using System.Collections.Generic;
 
class GFG{
     
// Function to find the
// minimum elements required to
// get the sum of given value S
static int printAllSubsetsRec(int[] arr, int n,
                            List v, int sum)
{
     
    // Condition if the
    // sequence is found
    if (sum == 0)
    {
        return v.Count;
    }
   
    if (sum < 0)
        return Int32.MaxValue;
          
    // Condition when no
    // such sequence found
    if (n == 0)
        return Int32.MaxValue;
   
    // Calling for without choosing
    // the current index value
    int x = printAllSubsetsRec(arr, n - 1,
                               v, sum);
   
    // Calling for after choosing
    // the current index value
    v.Add(arr[n - 1]);
      
    int y = printAllSubsetsRec(arr, n, v,
                               sum - arr[n - 1]);
    v.RemoveAt(v.Count - 1);
      
    return Math.Min(x, y);
}
  
// Function for every array
static int printAllSubsets(int[] arr, int n,
                           int sum)
{
    List v = new List();
    return printAllSubsetsRec(arr, n, v, sum);
}
 
// Driver code 
static void Main()
{
    int[] arr = { 2, 1, 4, 3, 5, 6 };
    int sum = 6;
    int n = arr.Length;
 
    Console.WriteLine(printAllSubsets(arr, n, sum));
}
}
 
// This code is contributed by divyeshrabadiya07


C++
// C++ implementation to find the
// minimum number of sequence
// required from array such that
// their sum is equal to given S
 
#include 
using namespace std;
 
// Function to find the count of
// minimum length of the sequence
int Count(int S[], int m, int n)
{
    vector > table(
        m + 1,
        vector(
            n + 1, 0));
 
    // Loop to intialize the array
    // as infinite in the row 0
    for (int i = 1; i <= n; i++) {
        table[0][i] = INT_MAX - 1;
    }
 
    // Loop to find the solution
    // by pre-computation for the
    // sequence
    for (int i = 1; i <= m; i++) {
 
        for (int j = 1; j <= n; j++) {
            if (S[i - 1] > j) {
                table[i][j]
                    = table[i - 1][j];
            }
            else {
 
                // Minimum possible
                // for the previous
                // minimum value
                // of the sequence
                table[i][j]
                    = min(
                        table[i - 1][j],
                        table[i][j - S[i - 1]] + 1);
            }
        }
    }
    return table[m][n];
}
 
// Driver Code
int main()
{
    int arr[] = { 9, 6, 5, 1 };
    int m = sizeof(arr) / sizeof(arr[0]);
    cout << Count(arr, m, 11);
    return 0;
}


Java
// Java implementation to find the
// minimum number of sequence
// required from array such that
// their sum is equal to given S
import java.util.*;
 
class GFG{
 
// Function to find the count of
// minimum length of the sequence
static int Count(int S[], int m, int n)
{
    int [][]table = new int[m + 1][n + 1];
 
    // Loop to intialize the array
    // as infinite in the row 0
    for(int i = 1; i <= n; i++)
    {
    table[0][i] = Integer.MAX_VALUE - 1;
    }
 
    // Loop to find the solution
    // by pre-computation for the
    // sequence
    for(int i = 1; i <= m; i++)
    {
    for(int j = 1; j <= n; j++)
    {
        if (S[i - 1] > j)
        {
            table[i][j] = table[i - 1][j];
        }
        else
        {
                 
            // Minimum possible for the
            // previous minimum value
            // of the sequence
            table[i][j] = Math.min(table[i - 1][j],
                            table[i][j - S[i - 1]] + 1);
        }
    }
    }
    return table[m][n];
}
 
// Driver Code
public static void main(String[] args)
{
    int arr[] = { 9, 6, 5, 1 };
    int m = arr.length;
     
    System.out.print(Count(arr, m, 11));
}
}
 
// This code is contributed by gauravrajput1


Python3
# Python3 implementation to find the
# minimum number of sequence
# required from array such that
# their sum is equal to given S
 
# Function to find the count of
# minimum length of the sequence
def Count(S, m, n):
    table = [[0 for i in range(n + 1)]
                for i in range(m + 1)]
 
    # Loop to intialize the array
    # as infinite in the row 0
    for i in range(1, n + 1):
        table[0][i] = 10**9 - 1
 
    # Loop to find the solution
    # by pre-computation for the
    # sequence
    for i in range(1, m + 1):
 
        for j in range(1, n + 1):
            if (S[i - 1] > j):
                table[i][j] = table[i - 1][j]
            else:
 
                # Minimum possible
                # for the previous
                # minimum value
                # of the sequence
                table[i][j] = min(table[i - 1][j],
                                table[i][j - S[i - 1]] + 1)
 
    return table[m][n]
 
# Driver Code
if __name__ == '__main__':
    arr= [9, 6, 5, 1]
    m = len(arr)
    print(Count(arr, m, 11))
 
# This code is contributed by Mohit Kumar


C#
// C# implementation to find the
// minimum number of sequence
// required from array such that
// their sum is equal to given S
using System;
 
class GFG{
 
// Function to find the count of
// minimum length of the sequence
static int Count(int[] S, int m, int n)
{
    int[,] table = new int[m + 1, n + 1];
 
    // Loop to intialize the array
    // as infinite in the row 0
    for(int i = 1; i <= n; i++)
    {
    table[0, i] = int.MaxValue - 1;
    }
 
    // Loop to find the solution
    // by pre-computation for the
    // sequence
    for(int i = 1; i <= m; i++)
    {
    for(int j = 1; j <= n; j++)
    {
        if (S[i - 1] > j)
        {
            table[i, j] = table[i - 1, j];
        }
        else
        {
                 
            // Minimum possible for the
            // previous minimum value
            // of the sequence
            table[i, j] = Math.Min(table[i - 1, j],
                            table[i, j - S[i - 1]] + 1);
        }
    }
    }
    return table[m, n];
}
 
// Driver Code
public static void Main(String[] args)
{
    int[] arr = { 9, 6, 5, 1 };
    int m = 4;
 
    Console.WriteLine(Count(arr, m, 11));
}
}
 
// This code is contributed by jrishabh99


输出:
1

性能分析:

  • 时间复杂度:与上述方法一样,每个步骤中的每个数字都有两个选择,占用O(2 N )时间,因此时间复杂度将为O(2 N )
  • 空间复杂度:与上述方法一样,没有使用额外的空间,因此空间复杂度将为O(1)

高效的方法:与上述方法一样,存在重叠的子问题,因此该想法是使用动态编程范例来解决此问题。创建一个N * S的DP表,以存储前一个序列的预先计算出的答案,该序列是获得总和所需的最小长度序列,即S – arr [i],这样就可以计算出每个序列的最终值。数组,问题的答案将是dp [N] [S],其中m是数组的长度,S是给定的和。

下面是上述方法的实现:

C++

// C++ implementation to find the
// minimum number of sequence
// required from array such that
// their sum is equal to given S
 
#include 
using namespace std;
 
// Function to find the count of
// minimum length of the sequence
int Count(int S[], int m, int n)
{
    vector > table(
        m + 1,
        vector(
            n + 1, 0));
 
    // Loop to intialize the array
    // as infinite in the row 0
    for (int i = 1; i <= n; i++) {
        table[0][i] = INT_MAX - 1;
    }
 
    // Loop to find the solution
    // by pre-computation for the
    // sequence
    for (int i = 1; i <= m; i++) {
 
        for (int j = 1; j <= n; j++) {
            if (S[i - 1] > j) {
                table[i][j]
                    = table[i - 1][j];
            }
            else {
 
                // Minimum possible
                // for the previous
                // minimum value
                // of the sequence
                table[i][j]
                    = min(
                        table[i - 1][j],
                        table[i][j - S[i - 1]] + 1);
            }
        }
    }
    return table[m][n];
}
 
// Driver Code
int main()
{
    int arr[] = { 9, 6, 5, 1 };
    int m = sizeof(arr) / sizeof(arr[0]);
    cout << Count(arr, m, 11);
    return 0;
}

Java

// Java implementation to find the
// minimum number of sequence
// required from array such that
// their sum is equal to given S
import java.util.*;
 
class GFG{
 
// Function to find the count of
// minimum length of the sequence
static int Count(int S[], int m, int n)
{
    int [][]table = new int[m + 1][n + 1];
 
    // Loop to intialize the array
    // as infinite in the row 0
    for(int i = 1; i <= n; i++)
    {
    table[0][i] = Integer.MAX_VALUE - 1;
    }
 
    // Loop to find the solution
    // by pre-computation for the
    // sequence
    for(int i = 1; i <= m; i++)
    {
    for(int j = 1; j <= n; j++)
    {
        if (S[i - 1] > j)
        {
            table[i][j] = table[i - 1][j];
        }
        else
        {
                 
            // Minimum possible for the
            // previous minimum value
            // of the sequence
            table[i][j] = Math.min(table[i - 1][j],
                            table[i][j - S[i - 1]] + 1);
        }
    }
    }
    return table[m][n];
}
 
// Driver Code
public static void main(String[] args)
{
    int arr[] = { 9, 6, 5, 1 };
    int m = arr.length;
     
    System.out.print(Count(arr, m, 11));
}
}
 
// This code is contributed by gauravrajput1

Python3

# Python3 implementation to find the
# minimum number of sequence
# required from array such that
# their sum is equal to given S
 
# Function to find the count of
# minimum length of the sequence
def Count(S, m, n):
    table = [[0 for i in range(n + 1)]
                for i in range(m + 1)]
 
    # Loop to intialize the array
    # as infinite in the row 0
    for i in range(1, n + 1):
        table[0][i] = 10**9 - 1
 
    # Loop to find the solution
    # by pre-computation for the
    # sequence
    for i in range(1, m + 1):
 
        for j in range(1, n + 1):
            if (S[i - 1] > j):
                table[i][j] = table[i - 1][j]
            else:
 
                # Minimum possible
                # for the previous
                # minimum value
                # of the sequence
                table[i][j] = min(table[i - 1][j],
                                table[i][j - S[i - 1]] + 1)
 
    return table[m][n]
 
# Driver Code
if __name__ == '__main__':
    arr= [9, 6, 5, 1]
    m = len(arr)
    print(Count(arr, m, 11))
 
# This code is contributed by Mohit Kumar

C#

// C# implementation to find the
// minimum number of sequence
// required from array such that
// their sum is equal to given S
using System;
 
class GFG{
 
// Function to find the count of
// minimum length of the sequence
static int Count(int[] S, int m, int n)
{
    int[,] table = new int[m + 1, n + 1];
 
    // Loop to intialize the array
    // as infinite in the row 0
    for(int i = 1; i <= n; i++)
    {
    table[0, i] = int.MaxValue - 1;
    }
 
    // Loop to find the solution
    // by pre-computation for the
    // sequence
    for(int i = 1; i <= m; i++)
    {
    for(int j = 1; j <= n; j++)
    {
        if (S[i - 1] > j)
        {
            table[i, j] = table[i - 1, j];
        }
        else
        {
                 
            // Minimum possible for the
            // previous minimum value
            // of the sequence
            table[i, j] = Math.Min(table[i - 1, j],
                            table[i, j - S[i - 1]] + 1);
        }
    }
    }
    return table[m, n];
}
 
// Driver Code
public static void Main(String[] args)
{
    int[] arr = { 9, 6, 5, 1 };
    int m = 4;
 
    Console.WriteLine(Count(arr, m, 11));
}
}
 
// This code is contributed by jrishabh99
输出:
2

性能分析:

  • 时间复杂度:与上述方法一样,有两个循环用于计算所需的最小长度序列,这需要O(N 2 )时间,因此时间复杂度将为O(N 2 )
  • 空间复杂度:与上述方法一样,使用了额外的dp表,因此空间复杂度将为O(N 2 )