Open In App

Minimum Number of Coins in a Bag

Last Updated : 29 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] where each element represents the number of coins in the bag, also given an integer k, minimize the maximum number of coins present in any bag using at most k operations, In each operation the coins in one bag can be distributed into two bags.

Examples:

Input: arr[] = [9], k = 2
Output: 3
Explanation:

  • Divide the bag with 9 coins into two bags of sizes 6 and 3. [9] -> [6,3].
  • Divide the bag with 6 coins into two bags of sizes 3 and 3. [6,3] -> [3,3,3].
  • The bag with the most number of coins has 3 coins in it.

Input: arr[] = [3, 4, 8], k = 2
Output: 4
Explantion:

  • Divide the bag with 8 coins into two bags of sizes 4 and 4. [3, 4, 8] -> [3, 4, 4, 4].
  • Divide the bag with 4 coins into two bags of sizes 3 and 1. [3, 4, 4, 4] -> [3, 4, 4, 3, 1].
  • The bag with the most number of coins has 4 coins in it.

Approach: To solve the problem follow the below idea:

This problem can be solved using the Binary search , since we need to minimize the maximum bag size we can apply the binary search on the bag size since the maximum bag size can’t be more the maximum element in the array. So applying the binary on the size of the bag and check if we split in that particular size we were able to finish it in less than equal to k operations while minimising it.

Follow these steps to solve the above problem:

  • Initialize low as mid and high as max value based on the constraint
  • Perform binary search while low<=mid
  • In the validBagSplit() function count the operations required for split the each bag into bag size of mid.
    • If the bag size is exactly divisible by mid then (arr[i] / mid) – 1 more operations need to split into extra (arr[i] / mid) – 1 bags.
    • Else it need arr[i] / mid more operations to split to more (arr[i] / mid) bags.
  • Check if dividing each bag in the size of mid is consuming greater than k operations, if its consuming assign the low as mid +1.
  • If dividing each bag in the size of mid is consuming less than equal to k operations check if we can minimize the bag size and store it in the result variable.
  • Return the result.

Below is the implementation for the above approach:

C++




// C++ code for the above approach:
#include <bits/stdc++.h>
using namespace std;
// Function to check the size is vaild or not
bool validBagSplit(vector<int>& arr, int k, int mid)
{
 
    int operations = 0;
    for (int i = 0; i < arr.size(); i++) {
 
        // If the bag size is exactly divisible
        // by mid then (arr[i] / mid) - 1 more
        // ops need to split into extra
        // (arr[i] / mid) - 1 bags
        if (arr[i] % mid == 0) {
            operations += arr[i] / mid - 1;
        }
 
        // Else it need arr[i] / mid more ops
        // to split to more arr[i] / mid bags
        else
            operations += arr[i] / mid;
    }
 
    if (operations <= k)
        return true;
    return false;
}
 
int minimizedMaxbagsize(vector<int>& arr, int k)
{
    // Initialize low as mid and high as max
    // value based on the constraint
    int low = 1;
    int high = 99999;
    int res = high;
 
    // Perform binary search while low<=mid
    while (low <= high) {
        int mid = low + (high - low) / 2;
        // Check if dividing each bag in the
        // size of mid is consuming > k
        // operations, if its consuming assign
        // the low as mid +1
        if (!validBagSplit(arr, k, mid))
            low = mid + 1;
        else {
 
            // If dividing each bag in the size
            // of mid is consuming <= k operations
            // check we can minimize the bag size
            // and store it in the res variable
            high = mid - 1;
            res = min(res, mid);
        }
    }
 
    // Return the result
    return res;
}
 
// Driver code
int main()
{
    vector<int> arr = { 9 };
    int k = 2;
 
    // Function Call
    cout << minimizedMaxbagsize(arr, k);
    return 0;
}


Java




import java.util.*;
 
public class Main {
 
    // Function to check if the size is valid or not
    static boolean validBagSplit(ArrayList<Integer> arr,
                                 int k, int mid)
    {
 
        int operations = 0;
        for (int i = 0; i < arr.size(); i++) {
 
            // If the bag size is exactly divisible
            // by mid then (arr[i] / mid) - 1 more
            // ops need to split into extra
            // (arr[i] / mid) - 1 bags
            if (arr.get(i) % mid == 0) {
                operations += arr.get(i) / mid - 1;
            }
 
            // Else it needs arr[i] / mid more ops
            // to split into more arr[i] / mid bags
            else
                operations += arr.get(i) / mid;
        }
 
        return operations <= k;
    }
 
    static int minimizedMaxBagSize(ArrayList<Integer> arr,
                                   int k)
    {
        // Initialize low as mid and high as max
        // value based on the constraint
        int low = 1;
        int high = 99999;
        int res = high;
 
        // Perform binary search while low <= mid
        while (low <= high) {
            int mid = low + (high - low) / 2;
 
            // Check if dividing each bag in the
            // size of mid is consuming > k
            // operations, if it's consuming assign
            // low as mid + 1
            if (!validBagSplit(arr, k, mid))
                low = mid + 1;
            else {
 
                // If dividing each bag in the size
                // of mid is consuming <= k operations
                // check if we can minimize the bag size
                // and store it in the res variable
                high = mid - 1;
                res = Math.min(res, mid);
            }
        }
 
        // Return the result
        return res;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        ArrayList<Integer> arr
            = new ArrayList<>(Arrays.asList(9));
        int k = 2;
 
        // Function Call
        System.out.println(minimizedMaxBagSize(arr, k));
    }
}


Python3




def valid_bag_split(arr, k, mid):
    operations = 0
    for i in range(len(arr)):
        if arr[i] % mid == 0:
            operations += arr[i] // mid - 1
        else:
            operations += arr[i] // mid
     
    return operations <= k
 
def minimized_max_bag_size(arr, k):
    low = 1
    high = 99999
    res = high
 
    while low <= high:
        mid = low + (high - low) // 2
 
        if not valid_bag_split(arr, k, mid):
            low = mid + 1
        else:
            high = mid - 1
            res = min(res, mid)
     
    return res
 
# Driver code
arr = [9]
k = 2
 
# Function Call
print(minimized_max_bag_size(arr, k))


C#




using System;
using System.Collections.Generic;
 
public class GFG
{
    // Function to check if the size is valid or not
    static bool ValidBagSplit(List<int> arr, int k, int mid)
    {
        int operations = 0;
        foreach (int val in arr)
        {
            // If the bag size is exactly divisible
            // by mid then (val / mid) - 1 more
            // ops need to split into extra
            // (val / mid) - 1 bags
            if (val % mid == 0)
            {
                operations += val / mid - 1;
            }
            else
            {
                // Else it needs val / mid more ops
                // to split into more val / mid bags
                operations += val / mid;
            }
        }
 
        return operations <= k;
    }
 
    static int MinimizedMaxBagSize(List<int> arr, int k)
    {
        // Initialize low as mid and high as max
        // value based on the constraint
        int low = 1;
        int high = 99999;
        int res = high;
 
        // Perform binary search while low <= mid
        while (low <= high)
        {
            int mid = low + (high - low) / 2;
 
            // Check if dividing each bag in the
            // size of mid is consuming > k
            // operations, if it's consuming assign
            // low as mid + 1
            if (!ValidBagSplit(arr, k, mid))
            {
                low = mid + 1;
            }
            else
            {
                // If dividing each bag in the size
                // of mid is consuming <= k operations
                // check if we can minimize the bag size
                // and store it in the res variable
                high = mid - 1;
                res = Math.Min(res, mid);
            }
        }
 
        // Return the result
        return res;
    }
 
    // Driver code
    public static void Main()
    {
        List<int> arr = new List<int> { 9 };
        int k = 2;
 
        // Function Call
        Console.WriteLine(MinimizedMaxBagSize(arr, k));
    }
}
//This code is contributed by rohit singh


Javascript




<script>
 
// Function to check if the bag size is valid or not
function validBagSplit(arr, k, mid) {
    let operations = 0;
 
    for (let i = 0; i < arr.length; i++) {
        // If the bag size is exactly divisible by mid
        // then (arr[i] / mid) - 1 more ops need to split
        if (arr[i] % mid === 0) {
            operations += arr[i] / mid - 1;
        } else {
            // Else, it needs arr[i] / mid more ops to split
            operations += Math.floor(arr[i] / mid);
        }
    }
 
    return operations <= k;
}
 
function minimizedMaxBagSize(arr, k) {
    // Initialize low as mid and high as max value based on the constraint
    let low = 1;
    let high = 99999;
    let res = high;
 
    // Perform binary search while low <= mid
    while (low <= high) {
        let mid = Math.floor(low + (high - low) / 2);
 
        // Check if dividing each bag in the size of mid consumes > k operations
        // If it consumes, assign low as mid + 1
        if (!validBagSplit(arr, k, mid)) {
            low = mid + 1;
        } else {
            // If dividing each bag in the size of mid consumes <= k operations,
            // check if we can minimize the bag size and store it in the res variable
            high = mid - 1;
            res = Math.min(res, mid);
        }
    }
 
    // Return the result
    return res;
}
 
// Driver code
const arr = [9];
const k = 2;
 
// Function Call
console.log(minimizedMaxBagSize(arr, k));
 
 
</script>


Output

3









Time Complexity: O(n*log n) where n is the size of the array
Auxiliary Space: O(1)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads