给定的阵列ARR []由N的正整数,使得ARR [i]表示第i个组坐在甜甜圈店和一个正整数k,这表示可以在间歇投放甜甜圈的最大数量的大小,任务是找到如果同一组的顾客一起服务,可以接收新鲜甜甜圈的最大组数。
注意:一组中的所有客户都不会收到上一批剩余的甜甜圈。
例子:
Input: arr[] = {1, 2, 3, 4, 5, 6}, K = 3
Output: 4
Explanation: One possible way for the ordering of the groups is {6, 2, 4, 5, 1, 3}.
- arr[0](= 6), The shops serve two batches of 3 donuts. So everyone gets fresh donuts.
- arr[1](= 2), The shop serves 3 fresh donuts, among which 1 gets left out. So everyone gets fresh donuts.
- arr[2](= 4), The shop serves first 1 leftover donut and then serves 3 fresh donuts.
- arr[1](= 5), The shop serves 6 fresh donuts, among which 1 is left out. So everyone gets fresh donuts.
- arr[1](= 1), The shop serves 1 leftover donut.
- arr[1](= 3), The shop serves 3 fresh donuts. So everyone gets fresh donuts.
Therefore, a total of 4 groups get fresh donuts which is the maximum possible number of groups.
Input: arr[] = {1, 3, 2, 5, 2, 2, 1, 6}, K = 4
Output: 4
朴素的方法:给定的问题可以通过对所有可能的排序使用回溯来解决,这基于观察到的每个组大小的余数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) + 1和res的最大值。
- 对于回溯步骤,将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 现场工作专业课程和学生竞争性编程现场课程。