给定一个整数S和一个数组arr [] ,任务是找到总和为S的最小元素数,以便可以选择任意次数数组中的任何元素以获得总和S。
例子:
Input: arr[] = {25, 10, 5}, S = 30
Output: 2
Explanation:
In the given array there are many possible solutions such as –
5 + 5 + 5 + 5 + 5 + 5 = 30, or
10 + 10 + 10 = 30, or
25 + 5 = 30
Hence, the minimum possible solution is 2
Input: arr[] = {2, 1, 4, 3, 5, 6}, Sum= 6
Output: 1
Explanation:
In the given array there are many possible solutions such as –
2 + 2 + 2 = 6, or
2 + 4 = 6, or
6 = 6,
Hence, the minimum possible solution is 1
方法:
想法是递归地找到每个可能的序列,以使它们的总和等于给定的S,并跟踪最小序列,以使它们的总和为S。这样,可以很容易地计算出最小的可能解。
下面是上述方法的实现:
C++
// C++ implmentation 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 implmentation 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 implmentation 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# implmentation 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++ implmentation 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 implmentation 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 implmentation 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# implmentation 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++ implmentation 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 implmentation 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 implmentation 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# implmentation 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 ) 。