Maximum number of groups of size 3 containing two type of items

Given n instance of item A and m instance of item B. Find the maximum number of groups of size 3 that can be formed using these items such that all groups contain items of both types, i.e., a group should not have either all items of type A or all items of type B. 
The total number of items of type A in the formed groups must be less than or equal to n. 
The total number of items of type B in the formed groups must be less than or equal to m.
Examples : 

Input : n = 2 and m = 6.
Output : 2
In group 1, one item of type A and two items of
type B. Similarly, in the group 2, one item of
type A and two items of type B.
We have used 2 (<= n) items of type A and 4 (<= m)
items of type B.
Input : n = 4 and m = 5.
Output : 3
In group 1, one item of type A and two items of type B.
In group 2, one item of type B and two items of type A.
In group 3, one item of type A and two items of type B.
We have used 4 (<= n) items of type A and 5 (<= 5)
items of type B.

Observation: 
1. There will be n groups possible if m >= 2n. Or there will be m groups possible, if n >= 2m. 
2. Suppose n = 3 and m = 3, so one instance of item A will make a group with the two instance of item B and one instance of item B will make a group with the two instance of item A. So, maximum two groups are possible. So find the total number of such conditions with given n and m by dividing m and m by 3. After this, there can be 0, 1, 2 instances of each type can be left. For finding the number of groups for the left instances: 
     a) If n = 0 or m = 0, 0 group is possible. 
     b) If n + m >= 3, only 1 group is possible.
Algorithm for solving this problem: 
1. If n >= 2m, maximum number of groups = n. 
2. Else if m >= 2n, maximum number of groups = m. 
3. Else If (m + n) % 3 == 0, maximum number of group = (m + n)/3; 
4. Else maximum number of group = (n + m)/3. And set n = n%3 and m = m%3. 
     a) If n != 0 && m != 0 && (n + m) >= 3, add one to maximum number of groups.
Below is the implementation of the above idea : 

C++




// C++ program to calculate
// maximum number of groups
#include<bits/stdc++.h>
 
using namespace std;
 
// Implements above mentioned steps.
int maxGroup(int n, int m)
{
    if (n >= 2 * m)
        return n;
    if (m >= 2 * n)
        return m;
    if ((m + n) % 3 == 0)
        return (m + n)/3;
 
    int ans = (m + n)/3;
    m %= 3;
    n %= 3;
 
    if (m && n && (m + n) >= 3)
        ans++;
 
    return ans;
}
 
// Driver code
int main()
{
    int n = 4, m = 5;
    cout << maxGroup(n, m) << endl;
    return 0;
}


Java




// Java program to calculate
// maximum number of groups
import java.io.*;
 
public class GFG{
     
// Implements above mentioned steps.
static int maxGroup(int n, int m)
{
    if (n >= 2 * m)
        return n;
    if (m >= 2 * n)
        return m;
    if ((m + n) % 3 == 0)
        return (m + n) / 3;
 
    int ans = (m + n) / 3;
    m %= 3;
    n %= 3;
 
    if (m > 0 && n > 0 && (m + n) >= 3)
        ans++;
 
    return ans;
}
 
    // Driver code
    static public void main (String[] args)
    {
            int n = 4, m = 5;
    System.out.println(maxGroup(n, m));
    }
}
 
// This code is contributed by vt_m.


Python3




# Python3 program to calculate maximum
# number of groups
 
# Implements above mentioned steps
def maxGroup(n, m):
     
    if n >= 2 * m:
        return n
    if m >= 2 * n:
        return m
    if (m + n) % 3 == 0:
        return (m + n) // 3
    ans = (m + n) // 3
    m = m % 3
    n = n % 3
     
    if m and n and (m + n) >= 3:
        ans += 1
    return ans
     
# Driver Code
n, m = 4, 5
print(maxGroup(n, m))
 
# This code is contributed
# by Mohit kumar 29


C#




// C# program to calculate
// maximum number of groups
using System;
 
public class GFG{
     
// Implements above mentioned steps.
static int maxGroup(int n, int m)
{
    if (n >= 2 * m)
        return n;
    if (m >= 2 * n)
        return m;
    if ((m + n) % 3 == 0)
        return (m + n) / 3;
 
    int ans = (m + n) / 3;
    m %= 3;
    n %= 3;
 
    if (m > 0 && n > 0 && (m + n) >= 3)
        ans++;
 
    return ans;
}
 
    // Driver code
    static public void Main ()
    {
        int n = 4, m = 5;
        Console.WriteLine(maxGroup(n, m));
    }
}
 
// This code is contributed by vt_m.


Javascript




<script>
 
// JavaScript program to find Cullen number
 
// Implements above mentioned steps.
function maxGroup(n, m)
{
    if (n >= 2 * m)
        return n;
    if (m >= 2 * n)
        return m;
    if ((m + n) % 3 == 0)
        return (m + n) / 3;
   
    let ans = (m + n) / 3;
    m %= 3;
    n %= 3;
   
    if (m > 0 && n > 0 && (m + n) >= 3)
        ans++;
   
    return ans;
}
 
// Driver Code
    let n = 4, m = 5;
    document.write(maxGroup(n, m));
 
// This code is contributed by chinmoy1997pal.
</script>


PHP




<?php
// PHP program to calculate
// maximum number of groups
 
// Implements above mentioned steps.
function maxGroup($n, $m)
{
    if ($n >= 2 * $m)
        return n;
    if ($m >= 2 * $n)
        return m;
    if ((($m + $n) % 3) == 0)
        return ($m + $n) / 3;
 
    $ans = ($m + $n) / 3;
    $m %= 3;
    $n %= 3;
 
    if ($m && $n && ($m + $n) >= 3)
        $ans++;
 
    return $ans;
}
 
// Driver code
$n = 4; $m = 5;
echo maxGroup($n, $m) ;
 
// This code is contributed
// by nitin mittal.
?>


Output

3




Time Complexity: O(1)
Auxiliary Space: O(1) 
 Using dynamic programing in python:

Approach:

We can also solve this problem using dynamic programming. We can define a two-dimensional table dp[i][j] where i represents the number of items of type A used so far, and j represents the number of items of type B used so far. The value of dp[i][j] represents the number of groups that can be formed using i items of type A and j items of type B. We can fill this table iteratively by considering each item of type A and type B and updating the corresponding entries in the table

C++




#include <iostream>
#include <vector>
 
using namespace std;
 
// Function to count the number of groups
int count_groups(int n, int m)
{
    vector<vector<int> > dp(n + 1, vector<int>(m + 1, 0));
    dp[0][0] = 1;
 
    // Update the recurring states
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= m; j++) {
            if (i > 0 && j >= 2) {
                dp[i][j] += dp[i - 1][j - 2];
            }
            if (j > 0 && i >= 2) {
                dp[i][j] += dp[i - 2][j - 1];
            }
        }
    }
    int count = 2;
 
    // Counting all possible groups
    for (int k = 1; k <= min(n, m / 2); k++) {
        count += dp[k][m - 2 * k];
    }
    return count;
}
 
// Driver Code
int main()
{
    int n = 2, m = 6;
    cout << count_groups(n, m) << endl;
    return 0;
}


Java




import java.util.Arrays;
 
class GFG {
    // Function to count the number of groups
    static int countGroups(int n, int m) {
        int[][] dp = new int[n + 1][m + 1];
        dp[0][0] = 1;
 
        // Update the recurring states
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= m; j++) {
                if (i > 0 && j >= 2) {
                    dp[i][j] += dp[i - 1][j - 2];
                }
                if (j > 0 && i >= 2) {
                    dp[i][j] += dp[i - 2][j - 1];
                }
            }
        }
 
        int count = 2;
 
        // Counting all possible groups
        for (int k = 1; k <= Math.min(n, m / 2); k++) {
            count += dp[k][m - 2 * k];
        }
 
        return count;
    }
 
    // Driver Code
    public static void main(String[] args) {
        int n = 2, m = 6;
        System.out.println(countGroups(n, m));
    }
}


Python3




def count_groups(n, m):
    dp = [[0]*(m+1) for _ in range(n+1)]
    dp[0][0] = 1
    for i in range(n+1):
        for j in range(m+1):
            if i > 0 and j >= 2:
                dp[i][j] += dp[i-1][j-2]
            if j > 0 and i >= 2:
                dp[i][j] += dp[i-2][j-1]
    count = 2
    for k in range(1, min(n, m//2)+1):
        count += dp[k][m-2*k]
    return count
 
n = 2
m = 6
print(count_groups(n, m))


C#




using System;
 
class Program
{
    // Function to count the number of groups
    static int CountGroups(int n, int m)
    {
        // Initialize a 2D array to store dynamic programming results
        int[,] dp = new int[n + 1, m + 1];
        dp[0, 0] = 1;
 
        // Update the recurring states
        for (int i = 0; i <= n; i++)
        {
            for (int j = 0; j <= m; j++)
            {
                if (i > 0 && j >= 2)
                {
                    dp[i, j] += dp[i - 1, j - 2];
                }
                if (j > 0 && i >= 2)
                {
                    dp[i, j] += dp[i - 2, j - 1];
                }
            }
        }
        int count = 2;
 
        // Counting all possible groups
        for (int k = 1; k <= Math.Min(n, m / 2); k++)
        {
            count += dp[k, m - 2 * k];
        }
        return count;
    }
 
    static void Main(string[] args)
    {
        int n = 2, m = 6;
        Console.WriteLine(CountGroups(n, m));
    }
}


Javascript




// Function to count the number of groups
function countGroups(n, m) {
    // Initialize a 2D array to store dynamic programming results
    let dp = new Array(n + 1).fill(0).map(() => new Array(m + 1).fill(0));
    dp[0][0] = 1;
 
    // Update the recurring states
    for (let i = 0; i <= n; i++) {
        for (let j = 0; j <= m; j++) {
            if (i > 0 && j >= 2) {
                dp[i][j] += dp[i - 1][j - 2];
            }
            if (j > 0 && i >= 2) {
                dp[i][j] += dp[i - 2][j - 1];
            }
        }
    }
    let count = 2;
 
    // Counting all possible groups
    for (let k = 1; k <= Math.min(n, Math.floor(m / 2)); k++) {
        count += dp[k][m - 2 * k];
    }
    return count;
}
 
// Driver Code
let n = 2, m = 6;
console.log(countGroups(n, m));


Output

2




Time complexity:
The time complexity of this program is O(nm), where n and m are the input parameters. This is because we create a 2D matrix of size (n+1) x (m+1) using nested loops, and then perform two more nested loops over the range (1, min(n, m//2)+1), resulting in an overall time complexity of O(nm).

Space complexity:
The space complexity of this program is O(nm), since we create a 2D matrix of size (n+1) x (m+1) to store intermediate results. The size of this matrix is proportional to the product of n and m, so the space complexity is O(nm). The other variables created in this program are of constant size, so they do not contribute significantly to the overall space complexity.