📌  相关文章
📜  使用给定容量的盒子时可能的最小堆叠数量

📅  最后修改于: 2021-05-06 08:36:01             🧑  作者: Mango

给定N个具有其容量的盒子,该数量表示它可以在其上面容纳的盒子总数。只要每个盒子上方的盒子总数小于或等于其容量,就可以将盒子彼此堆叠。通过使用所有框找到可堆叠的最小数量。
例子:

方法:让我们来一张地图,其中map [X]表示我们可以使用的容量为X的盒子数量。让我们一一构建堆栈。最初,堆栈的大小为0,然后,我们贪婪地遍历整个地图,并选择尽可能多的当前容量的框。
下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
 
// Function to return the count
// of minimum stacks
int countPiles(int n, int a[])
{
 
    // Keep track of occurrence
    // of each capacity
    map occ;
 
    // Fill the occurrence map
    for (int i = 0; i < n; i++)
        occ[a[i]]++;
 
    // Number of piles is 0 initially
    int pile = 0;
 
    // Traverse occurrences in increasing
    // order of capacities.
    while (occ.size()) {
 
        // Adding a new pile
        pile++;
        int size = 0;
        unordered_set toRemove;
 
        // Traverse all piles in increasing
        // order of capacities
        for (auto tm : occ) {
            int mx = tm.first;
            int ct = tm.second;
 
            // Number of boxes of capacity mx
            // that can be added to current pile
            int use = min(ct, mx - size + 1);
 
            // Update the occurrence
            occ[mx] -= use;
 
            // Update the size of the pile
            size += use;
            if (occ[mx] == 0)
                toRemove.insert(mx);
        }
 
        // Remove capacities that are
        // no longer available
        for (auto tm : toRemove)
            occ.erase(tm);
    }
    return pile;
}
 
// Driver code
int main()
{
    int a[] = { 0, 0, 1, 1, 2 };
    int n = sizeof(a) / sizeof(a[0]);
    cout << countPiles(n, a);
 
    return 0;
}


Java
// Java implementation of the approach
import java.util.HashMap;
import java.util.HashSet;
 
class GFG
{
 
    // Function to return the count
    // of minimum stacks
    static int countPiles(int n, int[] a)
    {
 
        // Keep track of occurrence
        // of each capacity
        HashMap occ = new HashMap<>();
 
        // Fill the occurrence map
        for (int i = 0; i < n; i++)
            occ.put(a[i], occ.get(a[i]) == null ? 1 :
                          occ.get(a[i]) + 1);
 
        // Number of piles is 0 initially
        int pile = 0;
 
        // Traverse occurrences in increasing
        // order of capacities.
        while (!occ.isEmpty())
        {
 
            // Adding a new pile
            pile++;
            int size = 0;
            HashSet toRemove = new HashSet<>();
 
            // Traverse all piles in increasing
            // order of capacities
            for (HashMap.Entry tm : occ.entrySet())
            {
                int mx = tm.getKey();
                int ct = tm.getValue();
 
                // Number of boxes of capacity mx
                // that can be added to current pile
                int use = Math.min(ct, mx - size + 1);
 
                // Update the occurrence
                occ.put(mx, occ.get(mx) - use);
 
                // Update the size of the pile
                size += use;
                if (occ.get(mx) == 0)
                    toRemove.add(mx);
            }
 
            // Remove capacities that are
            // no longer available
            for (int tm : toRemove)
                occ.remove(tm);
        }
        return pile;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int[] a = { 0, 0, 1, 1, 2 };
        int n = a.length;
 
        System.out.println(countPiles(n, a));
    }
}
 
// This code is contributed by
// sanjeev2552


Python3
# Python3 implementation of the approach
 
# Function to return the count
# of minimum stacks
def countPiles(n, a):
     
    # Keep track of occurrence
    # of each capacity
    occ = dict()
 
    # Fill the occurrence map
    for i in a:
        if i in occ.keys():
            occ[i] += 1
        else:
            occ[i] = 1
 
    # Number of piles is 0 initially
    pile = 0
 
    # Traverse occurrences in increasing
    # order of capacities.
    while (len(occ) > 0):
 
        # Adding a new pile
        pile += 1
        size = 0
        toRemove = dict()
 
        # Traverse all piles in increasing
        # order of capacities
        for tm in occ:
            mx = tm
            ct = occ[tm]
 
            # Number of boxes of capacity mx
            # that can be added to current pile
            use = min(ct, mx - size + 1)
 
            # Update the occurrence
            occ[mx] -= use
 
            # Update the size of the pile
            size += use
            if (occ[mx] == 0):
                toRemove[mx] = 1
         
        # Remove capacities that are
        # no longer available
        for tm in toRemove:
            del occ[tm]
     
    return pile
 
# Driver code
a = [0, 0, 1, 1, 2]
n = len(a)
print(countPiles(n, a))
 
# This code is contributed
# by Mohit Kumar


C#
// C# implementation of the approach
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
 
class GFG
{
 
  // Function to return the count
  // of minimum stacks
  static int countPiles(int n, int[] a)
  {
 
    // Keep track of occurrence
    // of each capacity
    Dictionary occ = new Dictionary();
 
    // Fill the occurrence map
    for (int i = 0; i < n; i++)
    {
      if(!occ.ContainsKey(a[i]))
      {
        occ[a[i]]=0;
      }
 
      occ[a[i]]++;
    }
 
    // Number of piles is 0 initially
    int pile = 0;
 
    // Traverse occurrences in increasing
    // order of capacities.
    while(occ.Count!=0)
    {
 
      // Adding a new pile
      pile++;
      int size = 0;
      HashSet toRemove = new HashSet();
 
      Dictionary tmp = occ;
 
      // Traverse all piles in increasing
      // order of capacities
      foreach(var tm in occ.Keys.ToList())
      {
        int mx = tm;
        int ct = occ[tm];
 
        // Number of boxes of capacity mx
        // that can be added to current pile
        int use = Math.Min(ct, mx - size + 1);
 
        // Update the occurrence
        occ[mx]-= use;
 
        // Update the size of the pile
        size += use;
 
        if (occ[mx] == 0)
          toRemove.Add(mx);
      }
 
      occ = tmp;
       
      // Remove capacities that are
      // no longer available
      foreach(int tm in toRemove.ToList())
        occ.Remove(tm);
    }
    return pile;
  }
 
  // Driver Code
  public static void Main(string[] args)
  {
    int[] a = { 0, 0, 1, 1, 2 };
    int n = a.Length;
 
    Console.WriteLine(countPiles(n, a));
  }
}
 
//// This code is contributed by rutvik_56.


输出:
2

时间复杂度: O(NlogN)