📜  可以接收分批大小为 K 的新鲜甜甜圈的最大组数

📅  最后修改于: 2021-09-17 07:12:44             🧑  作者: Mango

给定的阵列ARR []N的正整数,使得ARR [i]表示i组坐在甜甜圈店和一个正整数k,这表示可以在间歇投放甜甜圈的最大数量的大小,任务是找到如果同一组的顾客一起服务,可以接收新鲜甜甜圈的最大组数。

注意:一组中的所有客户都不会收到上一批剩余的甜甜圈。

例子:

朴素的方法:给定的问题可以通过对所有可能的排序使用回溯来解决,这基于观察到的每个组大小的余数K ,只需要考虑。请按照以下步骤解决问题:

  • 初始化一个数组,比如大小为K 的V[] ,其中V[i]表示剩余i人的组数。
  • 使用变量i遍历数组arr[] ,对于每个arr[i] ,V[arr[i] % K] 的值增加1
  • 定义一个递归函数,比如dfs(V, left) ,其中left是上一批剩余甜甜圈的数量:
    • 将变量res初始化为0 ,以存储当前状态的结果。
    • 如果left 的值为0 ,则使用变量i在范围[1, K – 1] 中迭代并执行以下步骤:
      • V[i]的值减1并递归调用参数为left-i的函数
      • res更新为dfs(V, left – i) + 1res的最大值。
      • 对于回溯步骤,将V[i]的值增加1
    • 否则,重复与上述相同的步骤,但在这种情况下,不要将结果加1 ,因为所选组将获得剩余的甜甜圈。
    • 返回res的值。
  • 调用上面定义的递归函数dfs(V, 0)并将返回值存储在一个变量中,比如X
  • 最后,完成上述步骤后,打印V[0]X的和作为结果。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Recursive function to find the
// maximum number of groups that
// will receive fresh donuts
int dfs(int arr[], int left, int K)
{
   
    // Store the result for the
    // current state
    int q = 0;
 
    // Check if the leftover donuts
    // from the previous batch is 0
    if (left == 0) {
 
        // If true, then one by one
        // give the fresh donuts
        // to each group
        for (int i = 1; i < K; ++i) {
            if (arr[i] > 0) {
 
                // Decrement arr[i]
                arr[i]--;
 
                // Update the maximum
                // number of groups
                q = max(q, 1 + dfs(arr, K - i, K));
 
                // Increment arr[i]
                arr[i]++;
            }
        }
    }
 
    // Otherwise, traverse the given
    // array, arr[]
    else {
 
        for (int i = 1; i < K; ++i) {
            if (arr[i] > 0) {
 
                // Decrement arr[i]
                arr[i]--;
 
                int nleft
                    = (i <= left ? left - i : K + left - i);
 
                // Update the maximum
                // number of groups
                q = max(q, dfs(arr, nleft, K));
 
                // Increment arr[i]
                arr[i]++;
            }
        }
    }
 
    // Return the value of q
    return q;
}
 
// Function to find the maximum
// number of groups that will
// receive fresh donuts
int maxGroups(int K, int arr[], int n)
{
   
    // Stores count of remainder
    // by K
    int V[K] = { 0 };
 
    // Traverse the array arr[]
    for (int x = 0; x < n; x++)
        V[arr[x] % K]++;
 
    // Stores maximum number of groups
    int ans = V[0] + dfs(V, 0, K);
 
    // Return the answer
    return ans;
}
 
// Driver Code
int main()
{
    int arr[] = { 1, 2, 3, 4, 5, 6 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int K = 3;
 
    cout << maxGroups(K, arr, n);
 
    return 0;
}
 
// This code is contributed by Potta Lokesh


Java
// Java program for the above approach
 
import java.io.*;
import java.util.*;
 
class GFG {
 
    // Recursive function to find the
    // maximum number of groups that
    // will receive fresh donuts
    public static int dfs(int[] arr,
                          int left, int K)
    {
        // Store the result for the
        // current state
        int q = 0;
 
        // Check if the leftover donuts
        // from the previous batch is 0
        if (left == 0) {
 
            // If true, then one by one
            // give the fresh donuts
            // to each group
            for (int i = 1; i < K; ++i) {
                if (arr[i] > 0) {
 
                    // Decrement arr[i]
                    arr[i]--;
 
                    // Update the maximum
                    // number of groups
                    q = Math.max(
                        q, 1 + dfs(arr, K - i, K));
 
                    // Increment arr[i]
                    arr[i]++;
                }
            }
        }
 
        // Otherwise, traverse the given
        // array, arr[]
        else {
 
            for (int i = 1; i < K; ++i) {
                if (arr[i] > 0) {
 
                    // Decrement arr[i]
                    arr[i]--;
 
                    int nleft = (i <= left ? left - i
                                           : K + left - i);
 
                    // Update the maximum
                    // number of groups
                    q = Math.max(q, dfs(arr, nleft, K));
 
                    // Increment arr[i]
                    arr[i]++;
                }
            }
        }
 
        // Return the value of q
        return q;
    }
 
    // Function to find the maximum
    // number of groups that will
    // receive fresh donuts
    public static int maxGroups(int K,
                                int[] arr)
    {
        // Stores count of remainder
        // by K
        int V[] = new int[K];
 
        // Traverse the array arr[]
        for (int x : arr)
            V[x % K]++;
 
        // Stores maximum number of groups
        int ans = V[0] + dfs(V, 0, K);
 
        // Return the answer
        return ans;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int[] arr = { 1, 2, 3, 4, 5, 6 };
        int K = 3;
        System.out.println(
            maxGroups(K, arr));
    }
}


Python3
# Python 3 program for the above approach
 
# Recursive function to find the
# maximum number of groups that
# will receive fresh donuts
def dfs(arr, left, K):
   
    # Store the result for the
    # current state
    q = 0
 
    # Check if the leftover donuts
    # from the previous batch is 0
    if (left == 0):
 
        # If true, then one by one
        # give the fresh donuts
        # to each group
        for i in range(1,K,1):
            if (arr[i] > 0):
 
                # Decrement arr[i]
                arr[i] -= 1
 
                # Update the maximum
                # number of groups
                q = max(q, 1 + dfs(arr, K - i, K))
 
                # Increment arr[i]
                arr[i] += 1
 
    # Otherwise, traverse the given
    # array, arr[]
    else:
 
        for i in range(1,K,1):
            if (arr[i] > 0):
               
                # Decrement arr[i]
                arr[i] -= 1
 
                nleft = left - i if i <= left else K + left - i
 
                # Update the maximum
                # number of groups
                q = max(q, dfs(arr, nleft, K))
 
                # Increment arr[i]
                arr[i] += 1
 
    # Return the value of q
    return q
 
# Function to find the maximum
# number of groups that will
# receive fresh donuts
def maxGroups(K, arr, n):
   
    # Stores count of remainder
    # by K
    V = [0 for i in range(K)]
 
    # Traverse the array arr[]
    for x in range(n):
        V[arr[x] % K] += 1
 
    # Stores maximum number of groups
    ans = V[0] + dfs(V, 0, K)
 
    # Return the answer
    return ans
 
# Driver Code
if __name__ == '__main__':
    arr= [1, 2, 3, 4, 5, 6]
    n = len(arr)
    K = 3
 
    print(maxGroups(K, arr, n))
     
    # This code is contributed by SURENDRA_GANGWAR.


C#
// C# program for the above approach
using System;
 
class GFG{
 
// Recursive function to find the
// maximum number of groups that
// will receive fresh donuts
public static int dfs(int[] arr,
                      int left, int K)
{
     
    // Store the result for the
    // current state
    int q = 0;
 
    // Check if the leftover donuts
    // from the previous batch is 0
    if (left == 0)
    {
         
        // If true, then one by one
        // give the fresh donuts
        // to each group
        for(int i = 1; i < K; ++i)
        {
            if (arr[i] > 0)
            {
                 
                // Decrement arr[i]
                arr[i]--;
 
                // Update the maximum
                // number of groups
                q = Math.Max(q, 1 + dfs(arr, K - i, K));
 
                // Increment arr[i]
                arr[i]++;
            }
        }
    }
 
    // Otherwise, traverse the given
    // array, arr[]
    else
    {
        for(int i = 1; i < K; ++i)
        {
            if (arr[i] > 0)
            {
                 
                // Decrement arr[i]
                arr[i]--;
 
                int nleft = (i <= left ? left - i :
                             K + left - i);
 
                // Update the maximum
                // number of groups
                q = Math.Max(q, dfs(arr, nleft, K));
 
                // Increment arr[i]
                arr[i]++;
            }
        }
    }
 
    // Return the value of q
    return q;
}
 
// Function to find the maximum
// number of groups that will
// receive fresh donuts
public static int maxGroups(int K, int[] arr)
{
     
    // Stores count of remainder
    // by K
    int[] V = new int[K];
 
    // Traverse the array arr[]
    foreach(int x in arr)
        V[x % K]++;
 
    // Stores maximum number of groups
    int ans = V[0] + dfs(V, 0, K);
 
    // Return the answer
    return ans;
}
 
// Driver code
public static void Main(string[] args)
{
    int[] arr = { 1, 2, 3, 4, 5, 6 };
    int K = 3;
     
    Console.WriteLine(maxGroups(K, arr));
}
}
 
// This code is contributed by sanjoy_62


Javascript


Java
// Java program for the above approach
 
import java.io.*;
import java.util.*;
 
class GFG {
 
    // Stores the result of the same
    // recursive calls
    static HashMap memo;
 
    // Recursive function to find the
    // maximum number of groups that
    // will receive fresh donuts
    public static int dfs(int[] V,
                          int left, int K)
    {
        // Store the result for the
        // current state
        int q = 0;
 
        // Store the key and check
        // if it is present in the
        // hashmap
        String key = Arrays.toString(V);
        key += Integer.toString(left);
 
        // If already calculated
        if (memo.containsKey(key))
            return memo.get(key);
 
        // If left is 0
        else if (left == 0) {
 
            // Traverse the array arr[]
            for (int i = 1; i < K; ++i)
                if (V[i] > 0) {
 
                    // Decrement arr[i]
                    V[i]--;
 
                    // Update the maximum
                    // number of groups
                    q = Math.max(
                        q, 1 + dfs(V, K - i, K));
 
                    // Increment arr[i] by 1
                    V[i]++;
                }
        }
 
        // Otherwise, traverse the given
        // array arr[]
        else {
 
            for (int i = 1; i < K; ++i) {
                if (V[i] > 0) {
 
                    // Decrement arr[i]
                    V[i]--;
 
                    int nleft = i <= left ? left - i
                                          : K + left - i;
 
                    // Update the maximum
                    // number of groups
                    q = Math.max(q, dfs(V, nleft, K));
 
                    // Increment arr[i] by 1
                    V[i]++;
                }
            }
        }
 
        // Memoize the result and
        // return it
        memo.put(key, q);
 
        return q;
    }
 
    // Function to find the maximum
    // number of groups that will
    // receive fresh donuts
    public static int maxGroups(int K, int[] arr)
    {
        // Stores count of remainder by K
        int V[] = new int[K];
 
        // Traverse the array arr[]
        for (int x : arr)
            V[x % K]++;
 
        // Hashmap to memoize the results
        memo = new HashMap();
 
        // Store the maximum number
        // of groups
        int ans = V[0] + dfs(V, 0, K);
 
        // Return the answer
        return ans;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int[] arr = { 1, 2, 3, 4, 5, 6 };
        int K = 3;
        System.out.println(
            maxGroups(K, arr));
    }
}


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
public class GFG {
 
    // Stores the result of the same
    // recursive calls
    static Dictionary memo;
 
    // Recursive function to find the
    // maximum number of groups that
    // will receive fresh donuts
    public static int dfs(int[] V,
                          int left, int K)
    {
        // Store the result for the
        // current state
        int q = 0;
 
        // Store the key and check
        // if it is present in the
        // hashmap
        String key = string.Join(",", V);
        key += left.ToString();
        // If already calculated
        if (memo.ContainsKey(key))
            return memo[key];
 
        // If left is 0
        else if (left == 0) {
 
            // Traverse the array []arr
            for (int i = 1; i < K; ++i)
                if (V[i] > 0) {
 
                    // Decrement arr[i]
                    V[i]--;
 
                    // Update the maximum
                    // number of groups
                    q = Math.Max(
                        q, 1 + dfs(V, K - i, K));
 
                    // Increment arr[i] by 1
                    V[i]++;
                }
        }
 
        // Otherwise, traverse the given
        // array []arr
        else {
 
            for (int i = 1; i < K; ++i) {
                if (V[i] > 0) {
 
                    // Decrement arr[i]
                    V[i]--;
 
                    int nleft = i <= left ? left - i
                                          : K + left - i;
 
                    // Update the maximum
                    // number of groups
                    q = Math.Max(q, dfs(V, nleft, K));
 
                    // Increment arr[i] by 1
                    V[i]++;
                }
            }
        }
 
        // Memoize the result and
        // return it
        if(memo.ContainsKey(key))
            memo[key] = q;
        else
            memo.Add(key, q);
 
        return q;
    }
 
    // Function to find the maximum
    // number of groups that will
    // receive fresh donuts
    public static int maxGroups(int K, int[] arr)
    {
       
        // Stores count of remainder by K
        int []V = new int[K];
 
        // Traverse the array []arr
        foreach (int x in arr)
            V[x % K]++;
 
        // Hashmap to memoize the results
        memo = new Dictionary();
 
        // Store the maximum number
        // of groups
        int ans = V[0] + dfs(V, 0, K);
 
        // Return the answer
        return ans;
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        int[] arr = { 1, 2, 3, 4, 5, 6 };
        int K = 3;
        Console.WriteLine(
            maxGroups(K, arr));
    }
}
 
// This code is contributed by 29AjayKumar


输出:
4

时间复杂度: O(N + K K )
辅助空间: O(K)

高效方法:上述方法具有最优子结构和重叠子问题,因此,上述方法也可以通过将相同的递归调用记忆在一个 HashMap 中进行优化,并在递归调用相同问题时使用该状态。

下面是上述方法的实现:

Java

// Java program for the above approach
 
import java.io.*;
import java.util.*;
 
class GFG {
 
    // Stores the result of the same
    // recursive calls
    static HashMap memo;
 
    // Recursive function to find the
    // maximum number of groups that
    // will receive fresh donuts
    public static int dfs(int[] V,
                          int left, int K)
    {
        // Store the result for the
        // current state
        int q = 0;
 
        // Store the key and check
        // if it is present in the
        // hashmap
        String key = Arrays.toString(V);
        key += Integer.toString(left);
 
        // If already calculated
        if (memo.containsKey(key))
            return memo.get(key);
 
        // If left is 0
        else if (left == 0) {
 
            // Traverse the array arr[]
            for (int i = 1; i < K; ++i)
                if (V[i] > 0) {
 
                    // Decrement arr[i]
                    V[i]--;
 
                    // Update the maximum
                    // number of groups
                    q = Math.max(
                        q, 1 + dfs(V, K - i, K));
 
                    // Increment arr[i] by 1
                    V[i]++;
                }
        }
 
        // Otherwise, traverse the given
        // array arr[]
        else {
 
            for (int i = 1; i < K; ++i) {
                if (V[i] > 0) {
 
                    // Decrement arr[i]
                    V[i]--;
 
                    int nleft = i <= left ? left - i
                                          : K + left - i;
 
                    // Update the maximum
                    // number of groups
                    q = Math.max(q, dfs(V, nleft, K));
 
                    // Increment arr[i] by 1
                    V[i]++;
                }
            }
        }
 
        // Memoize the result and
        // return it
        memo.put(key, q);
 
        return q;
    }
 
    // Function to find the maximum
    // number of groups that will
    // receive fresh donuts
    public static int maxGroups(int K, int[] arr)
    {
        // Stores count of remainder by K
        int V[] = new int[K];
 
        // Traverse the array arr[]
        for (int x : arr)
            V[x % K]++;
 
        // Hashmap to memoize the results
        memo = new HashMap();
 
        // Store the maximum number
        // of groups
        int ans = V[0] + dfs(V, 0, K);
 
        // Return the answer
        return ans;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int[] arr = { 1, 2, 3, 4, 5, 6 };
        int K = 3;
        System.out.println(
            maxGroups(K, arr));
    }
}

C#

// C# program for the above approach
using System;
using System.Collections.Generic;
 
public class GFG {
 
    // Stores the result of the same
    // recursive calls
    static Dictionary memo;
 
    // Recursive function to find the
    // maximum number of groups that
    // will receive fresh donuts
    public static int dfs(int[] V,
                          int left, int K)
    {
        // Store the result for the
        // current state
        int q = 0;
 
        // Store the key and check
        // if it is present in the
        // hashmap
        String key = string.Join(",", V);
        key += left.ToString();
        // If already calculated
        if (memo.ContainsKey(key))
            return memo[key];
 
        // If left is 0
        else if (left == 0) {
 
            // Traverse the array []arr
            for (int i = 1; i < K; ++i)
                if (V[i] > 0) {
 
                    // Decrement arr[i]
                    V[i]--;
 
                    // Update the maximum
                    // number of groups
                    q = Math.Max(
                        q, 1 + dfs(V, K - i, K));
 
                    // Increment arr[i] by 1
                    V[i]++;
                }
        }
 
        // Otherwise, traverse the given
        // array []arr
        else {
 
            for (int i = 1; i < K; ++i) {
                if (V[i] > 0) {
 
                    // Decrement arr[i]
                    V[i]--;
 
                    int nleft = i <= left ? left - i
                                          : K + left - i;
 
                    // Update the maximum
                    // number of groups
                    q = Math.Max(q, dfs(V, nleft, K));
 
                    // Increment arr[i] by 1
                    V[i]++;
                }
            }
        }
 
        // Memoize the result and
        // return it
        if(memo.ContainsKey(key))
            memo[key] = q;
        else
            memo.Add(key, q);
 
        return q;
    }
 
    // Function to find the maximum
    // number of groups that will
    // receive fresh donuts
    public static int maxGroups(int K, int[] arr)
    {
       
        // Stores count of remainder by K
        int []V = new int[K];
 
        // Traverse the array []arr
        foreach (int x in arr)
            V[x % K]++;
 
        // Hashmap to memoize the results
        memo = new Dictionary();
 
        // Store the maximum number
        // of groups
        int ans = V[0] + dfs(V, 0, K);
 
        // Return the answer
        return ans;
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        int[] arr = { 1, 2, 3, 4, 5, 6 };
        int K = 3;
        Console.WriteLine(
            maxGroups(K, arr));
    }
}
 
// This code is contributed by 29AjayKumar
输出:
4

时间复杂度: O(N + K 2 )
辅助空间: O(K)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程