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!