Given arrays A[] and B[] of size N and integer M, the task is to find out the minimum operations required to collect a sum of at least M by performing the following operations any number of times. Either choosing the first element of A[] or the first element of B[] remove that element from the front and add that to the sum. Initially, the sum is zero.
Examples:
Input: A[] = {1, 9, 1, 4, 0, 1}, B[] = {3, 2, 1, 5, 9, 10}, M = 12
Output: 3
Explanation: Initially sum = 0
- Removing front element of array A[] which is 1 and adding it to sum, now sum = 1.
- Removing front element of array A[] which is 9 again and adding it to sum, now sum = 10.
- Removing front element of array B[] which is 3 and adding it to sum, now sum = 13.
As 13 is greater than equal to M. Hence in three operations sum greater than equal to M = 12 can be achieved.
Input: A[] = {0, 1, 2, 3, 5}, B[] = {5, 0, 0, 0, 9}, M = 6
Output: 3
Naive approach: The basic way to solve the problem is as follows:
The basic way to solve this problem is to generate all possible combinations by using a recursive approach.
Time Complexity: O(2N)
Auxiliary Space: O(1)
Efficient Approach: The above approach can be optimized based on the following idea:
Dynamic programming can be used to solve this problem
- dp[i][j][k] represents a minimum number of operations to make at least i from the first j elements of array A[] and first k elements of array B[], Here i represents the amount to be made, j represents the jth element of A[] and k represents the kth element of B[].
- It can be observed that the recursive function is called exponential times. That means that some states are called repeatedly. So the idea is to store the value of each state.
- This can be done using by the store the value of a state and whenever the function is called, returning the stored value without computing again.
Follow the steps below to solve the problem:
- Create a recursive function that takes three parameters i represents the amount to be made, j represents the jth element of A[] and k represents k’th element of B[].
- Create a 3d array dp[M][N][N] initially filled with -1.
- If the answer for a particular state is computed then save it in dp[i][j][k].
- if the answer for a particular state is already computed then just return dp[i][j][k].
- Base case if i becomes zero return 0.
- Call the recursive function for choosing both the jth element of A[] and k’th element of B[].
- return the dp value by dp[i][j][k] = ans.
Below is the implementation of the above approach:
C++
// C++ code to implement the approach #include <bits/stdc++.h> using namespace std; // dp table initialized with -1 int dp[501][101][101]; // Recursive Function to minimize the // operations to collect at least sum of M int solve( int i, int j, int k, int A[], int B[], int N) { // Base case if (i <= 0) { return 0; } // If answer for current state is // already calculated then just // return dp[i][j][k] if (dp[i][j][k] != -1) return dp[i][j][k]; // Answer initialized with zero int ans = 1e9; // Calling recursive function for // taking j'th element of array A[] if (j != N) ans = min(ans, solve(i - A[j], j + 1, k, A, B, N) + 1); // Calling recursive function for // taking k'th element of array B[] if (k != N) ans = min(ans, solve(i - B[k], j, k + 1, A, B, N) + 1); // Save and return dp value return dp[i][j][k] = ans; } // Function to minimize the operations // to collect at least sum of M int minOperations( int A[], int B[], int N, int M) { // Filling dp table with - 1 memset (dp, -1, sizeof (dp)); // Minimum operations int ans = solve(M, 0, 0, A, B, N); return ans; } // Driver Code int main() { // Input 1 int A[] = { 1, 9, 1, 4, 0, 1 }, B[] = { 3, 2, 1, 5, 9, 10 }; int N = sizeof (A) / sizeof (A[0]); int M = 12; // Function Call cout << minOperations(A, B, N, M) << endl; // Input 2 int A1[] = { 0, 1, 2, 3, 5 }, B1[] = { 5, 0, 0, 0, 9 }; int N1 = sizeof (A1) / sizeof (A1[0]); int M1 = 6; // Function Call cout << minOperations(A1, B1, N1, M1) << endl; return 0; } |
Java
// Java code to implement the approach import java.io.*; import java.util.*; class GFG { // dp table initialized with -1 static int [][][] dp = new int [ 501 ][ 101 ][ 101 ]; // Recursive Function to minimize the // operations to collect at least sum of M static int solve( int i, int j, int k, int [] A, int [] B, int N) { // Base case if (i <= 0 ) { return 0 ; } // If answer for current state is // already calculated then just // return dp[i][j][k] if (dp[i][j][k] != - 1 ) { return dp[i][j][k]; } // Answer initialized with zero int ans = ( int )1e9; // Calling recursive function for // taking j'th element of array A[] if (j != N) { ans = Math.min( ans, solve(i - A[j], j + 1 , k, A, B, N) + 1 ); } // Calling recursive function for // taking k'th element of array B[] if (k != N) { ans = Math.min( ans, solve(i - B[k], j, k + 1 , A, B, N) + 1 ); } // Save and return dp value return dp[i][j][k] = ans; } // Function to minimize the operations // to collect at least sum of M static int minOperations( int [] A, int [] B, int N, int M) { // Filling dp table with - 1 for ( int i = 0 ; i < dp.length; i++) { for ( int j = 0 ; j < dp[i].length; j++) { Arrays.fill(dp[i][j], - 1 ); } } // Minimum operations int ans = solve(M, 0 , 0 , A, B, N); return ans; } public static void main(String[] args) { // Input 1 int [] A = { 1 , 9 , 1 , 4 , 0 , 1 }, B = { 3 , 2 , 1 , 5 , 9 , 10 }; int N = A.length; int M = 12 ; // Function Call System.out.println(minOperations(A, B, N, M)); // Input 2 int [] A1 = { 0 , 1 , 2 , 3 , 5 }, B1 = { 5 , 0 , 0 , 0 , 9 }; int N1 = A1.length; int M1 = 6 ; // Function Call System.out.println(minOperations(A1, B1, N1, M1)); } } // This code is contributed by lokesh. |
Python3
# Python code for the above approach import sys from typing import List # dp table initialized with -1 dp = [[[ - 1 for _ in range ( 101 )] for _ in range ( 101 )] for _ in range ( 501 )] def solve(i: int , j: int , k: int , A: List [ int ], B: List [ int ], N: int ) - > int : # Base case if i < = 0 : return 0 # If answer for current state is already calculated then just return dp[i][j][k] if dp[i][j][k] ! = - 1 : return dp[i][j][k] # Answer initialized with big value ans = sys.maxsize # Calling recursive function for taking j'th element of array A[] if j ! = N: ans = min (ans, solve(i - A[j], j + 1 , k, A, B, N) + 1 ) # Calling recursive function for taking k'th element of array B[] if k ! = N: ans = min (ans, solve(i - B[k], j, k + 1 , A, B, N) + 1 ) # Save and return dp value dp[i][j][k] = ans return ans def minOperations(A: List [ int ], B: List [ int ], N: int , M: int ) - > int : # Minimum operations return solve(M, 0 , 0 , A, B, N) # Driver code A = [ 1 , 9 , 1 , 4 , 0 , 1 ] B = [ 3 , 2 , 1 , 5 , 9 , 10 ] N = len (A) M = 12 print (minOperations(A, B, N, M)) A1 = [ 0 , 1 , 2 , 3 , 5 ] B1 = [ 5 , 0 , 0 , 0 , 9 ] N1 = len (A1) M1 = 6 print (minOperations(A1, B1, N1, M1)) # This code is contributed by lokeshpotta20. |
C#
// C# code to implement the approach using System; using System.Linq; public class GFG { // dp table initialized with -1 static int [, , ] dp = new int [501, 101, 101]; // Recursive Function to minimize the // operations to collect at least sum of M static int Solve( int i, int j, int k, int [] A, int [] B, int N) { // Base case if (i <= 0) { return 0; } // If answer for current state is // already calculated then just // return dp[i][j][k] if (dp[i, j, k] != -1) { return dp[i, j, k]; } // Answer initialized with zero int ans = ( int )1e9; // Calling recursive function for // taking j'th element of array A[] if (j != N) { ans = Math.Min( ans, Solve(i - A[j], j + 1, k, A, B, N) + 1); } // Calling recursive function for // taking k'th element of array B[] if (k != N) { ans = Math.Min( ans, Solve(i - B[k], j, k + 1, A, B, N) + 1); } // Save and return dp value return dp[i, j, k] = ans; } // Function to minimize the operations // to collect at least sum of M static int MinOperations( int [] A, int [] B, int N, int M) { // Filling dp table with - 1 for ( int i = 0; i < dp.GetLength(0); i++) { for ( int j = 0; j < dp.GetLength(1); j++) { for ( int k = 0; k < dp.GetLength(2); k++) { dp[i, j, k] = -1; } } } // Minimum operations int ans = Solve(M, 0, 0, A, B, N); return ans; } static public void Main() { // Code // Input 1 int [] A = { 1, 9, 1, 4, 0, 1 }, B = { 3, 2, 1, 5, 9, 10 }; int N = A.Length; int M = 12; // Function Call Console.WriteLine(MinOperations(A, B, N, M)); // Input 2 int [] A1 = { 0, 1, 2, 3, 5 }, B1 = { 5, 0, 0, 0, 9 }; int N1 = A1.Length; int M1 = 6; // Function Call Console.WriteLine(MinOperations(A1, B1, N1, M1)); } } // This code is contributed by lokeshmvs21. |
Javascript
// dp table initialized with -1 let dp = new Array(501); for (let i = 0; i < 501; i++) { dp[i] = new Array(101); for (let j = 0; j < 101; j++) { dp[i][j] = new Array(101).fill(-1); } } // Recursive Function to minimize the // operations to collect at least sum of M function solve(i, j, k, A, B, N) { // Base case if (i <= 0) { return 0; } // If answer for current state is // already calculated then just // return dp[i][j][k] if (dp[i][j][k] !== -1) return dp[i][j][k]; // Answer initialized with zero let ans = 1e9; // Calling recursive function for // taking j'th element of array A[] if (j !== N) ans = Math.min(ans, solve(i - A[j], j + 1, k, A, B, N) + 1); // Calling recursive function for // taking k'th element of array B[] if (k !== N) ans = Math.min(ans, solve(i - B[k], j, k + 1, A, B, N) + 1); // Save and return dp value return dp[i][j][k] = ans; } // Function to minimize the operations // to collect at least sum of M function minOperations(A, B, N, M) { // Minimum operations let ans = solve(M, 0, 0, A, B, N); return ans; } // Input 1 let A = [1, 9, 1, 4, 0, 1]; let B = [3, 2, 1, 5, 9, 10]; let N = A.length; let M = 12; // Function Call console.log(minOperations(A, B, N, M)); // Input 2 let A1 = [0, 1, 2, 3, 5]; let B1 = [5, 0, 0, 0, 9]; let N1 = A1.length; let M1 = 6; // Function Call console.log(minOperations(A1, B1, N1, M1)); // This code is contributed by aadityamaharshi21. |
3 3
Time Complexity: O(N2 * M)
Auxiliary Space: O(N2 * M)
Related Articles:
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!