根据给定的规则,最小化 K 让人 A 消耗至少 ceil(N/(M + 1)) 个糖果
给定N个糖果, M个人,以及一个由M个正整数组成的数组arr[] ,任务是找到K的最小值,使得一个人 A能够消耗至少 ceil 的总数(N/(M + 1))糖果按照以下规则:
- 在第一回合中, A 人消耗了剩下的糖果数量和K中的最小值。
- 在接下来的M轮中,范围为 [0, M-1]的每个第 i个人消耗了arr[i]百分比的剩余糖果。
- 重复上述步骤,直到没有糖果。
例子:
Input: N = 13, M = 1, arr[] = {50}
Output: 3
Explanation:
For the value K as 3, the good share is the ceil of (13/2) = 7. Following are the turns that takes place:
- Person A takes min(3,13)=3 candies. Therefore, the candies left = 13 – 3 = 10.
- Person 0 takes arr[0](= 50)% of the 10 left candies, i.e., 5 candies. Therefore, the candies left = 10 – 5 = 5.
- Person A takes min(3,5)=3 candies. Therefore, the candies left = 5 – 3 = 2.
- Person 0 takes arr[0](= 50)% of the 2 left candies, i.e., 1 candies. Therefore, the candies left = 2 – 1 = 1.
- Person A takes 1 candy. Therefore, the candies left = 1 – 1 = 0.
After the above turns, the candies taken by the person is 3 + 3 + 1 = 7, which is at least (N/(M + 1)) candies, i.e., 13/2 = 6.
Input: N = 13, M = 2, arr[] = {40, 50}
Output: 2
朴素方法:解决给定问题的最简单方法是检查每个人 A将获得的糖果数量是否为K的所有可能值。请按照以下步骤解决此问题:
- 找到(N/(M + 1))的值并将其存储在一个变量中,说好,因为这是A想吃的最少糖果。
- 遍历[1, N]范围内的所有K值并执行以下步骤:
- 对于每个K值,模拟上面提到的过程并计算人 A将获得的糖果总数。
- 如果糖果的数量至少是good的值,则跳出循环。否则,继续迭代。
- 完成上述步骤后,打印出K的当前值作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find minimum value of
// K such that the first person gets
// at least (N/(M+1)) candies
void minimumK(vector &arr, int M,
int N)
{
// Find the minimum required value
// of candies for the first person
int good = ceil((N * 1.0)
/ ((M + 1) * 1.0));
// Iterate K from [1, n]
for (int i = 1; i <= N; i++) {
int K = i;
// Total number of candies
int candies = N;
// Candies taken by Person 1
int taken = 0;
while (candies > 0) {
// Candies taken by 1st
// person is minimum of K
// and candies left
taken += min(K, candies);
candies -= min(K, candies);
// Traverse the array arr[]
for (int j = 0; j < M; j++) {
// Amount consumed by the
// person j
int consume = (arr[j]
* candies) / 100;
// Update the number
// of candies
candies -= consume;
}
}
// Good share of candies achieved
if (taken >= good) {
cout << i;
return;
}
}
}
// Driver Code
int main()
{
int N = 13, M = 1;
vector arr = { 50 };
minimumK(arr, M, N);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to find minimum value of
// K such that the first person gets
// at least (N/(M+1)) candies
static void minimumK(ArrayList arr, int M,
int N)
{
// Find the minimum required value
// of candies for the first person
int good = (int)((N * 1.0) / ((M + 1) * 1.0)) + 1;
// Iterate K from [1, n]
for(int i = 1; i <= N; i++)
{
int K = i;
// Total number of candies
int candies = N;
// Candies taken by Person 1
int taken = 0;
while (candies > 0)
{
// Candies taken by 1st
// person is minimum of K
// and candies left
taken += Math.min(K, candies);
candies -= Math.min(K, candies);
// Traverse the array arr[]
for(int j = 0; j < M; j++)
{
// Amount consumed by the
// person j
int consume = (arr.get(j) * candies) / 100;
// Update the number
// of candies
candies -= consume;
}
}
// Good share of candies achieved
if (taken >= good)
{
System.out.print(i);
return;
}
}
}
// Driver Code
public static void main(String[] args)
{
int N = 13, M = 1;
ArrayList arr = new ArrayList();
arr.add(50);
minimumK(arr, M, N);
}
}
// This code is contributed by subhammahato348
Python3
# Python 3 program for the above approach
import math
# Function to find minimum value of
# K such that the first person gets
# at least (N/(M+1)) candies
def minimumK(arr, M, N):
# Find the minimum required value
# of candies for the first person
good = math.ceil((N * 1.0) / ((M + 1) * 1.0))
# Iterate K from [1, n]
for i in range(1, N + 1):
K = i
# Total number of candies
candies = N
# Candies taken by Person 1
taken = 0
while (candies > 0):
# Candies taken by 1st
# person is minimum of K
# and candies left
taken += min(K, candies)
candies -= min(K, candies)
# Traverse the array arr[]
for j in range(M):
# Amount consumed by the
# person j
consume = (arr[j]
* candies) / 100
# Update the number
# of candies
candies -= consume
# Good share of candies achieved
if (taken >= good):
print(i)
return
# Driver Code
if __name__ == "__main__":
N = 13
M = 1
arr = [50]
minimumK(arr, M, N)
# This code is contributed by ukasp.
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to find minimum value of
// K such that the first person gets
// at least (N/(M+1)) candies
static void minimumK(List arr, int M,
int N)
{
// Find the minimum required value
// of candies for the first person
int good = (int)((N * 1.0) / ((M + 1) * 1.0))+1;
// Iterate K from [1, n]
for (int i = 1; i <= N; i++) {
int K = i;
// Total number of candies
int candies = N;
// Candies taken by Person 1
int taken = 0;
while (candies > 0) {
// Candies taken by 1st
// person is minimum of K
// and candies left
taken += Math.Min(K, candies);
candies -= Math.Min(K, candies);
// Traverse the array arr[]
for (int j = 0; j < M; j++) {
// Amount consumed by the
// person j
int consume = (arr[j]
* candies) / 100;
// Update the number
// of candies
candies -= consume;
}
}
// Good share of candies achieved
if (taken >= good) {
Console.Write(i);
return;
}
}
}
// Driver Code
public static void Main()
{
int N = 13, M = 1;
List arr = new List();
arr.Add(50);
minimumK(arr, M, N);
}
}
// This code is contributed by SURENDRA_GANGWAR.
Javascript
C++
// C++ program for the above approach
#include
using namespace std;
// Function to check if the value of
// mid gives at least (N/(M + 1))
// candies or not
bool check(int K, int n, int m,
vector arr,
int good_share)
{
int candies = n, taken = 0;
while (candies > 0) {
// Candies taken by 1st
// person is minimum of K
// and candies left
taken += min(K, candies);
candies -= min(K, candies);
// Traverse the given array
for (int j = 0; j < m; j++) {
// Amount consumed by
// person j
int consume = (arr[j] * candies) / 100;
// Update the count of
// candies
candies -= consume;
}
}
// Check if person 1 gets the
// good share of candies
return (taken >= good_share);
}
// Function to find minimum value of
// K such that the first person gets
// at least (N/(M+1)) candies
void minimumK(vector &arr, int N,
int M)
{
// Find the minimum required value
// of candies for the first person
int good_share = ceil((N * 1.0)
/ ((M + 1) * 1.0));
int lo = 1, hi = N;
// Iterate until low is less
// than or equal to mid
while (lo < hi) {
// Find the value of mid
int mid = (lo + hi) / 2;
// Check for mid, whether it
// can be the possible value
// of K or not
if (check(mid, N, M, arr,
good_share)) {
// Update the value of hi
hi = mid;
}
// Otherwise, update the
// value of lo
else {
lo = mid + 1;
}
}
// Print the resultant minimum
// value of K
cout << hi;
}
// Driver Code
int main()
{
int N = 13, M = 1;
vector arr = { 50 };
minimumK(arr, N, M);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG {
// Function to check if the value of
// mid gives at least (N/(M + 1))
// candies or not
static boolean check(int K, int n, int m,
ArrayList arr,
int good_share)
{
int candies = n, taken = 0;
while (candies > 0) {
// Candies taken by 1st
// person is minimum of K
// and candies left
taken += Math.min(K, candies);
candies -= Math.min(K, candies);
// Traverse the given array
for (int j = 0; j < m; j++) {
// Amount consumed by
// person j
int consume = (arr.get(j) * candies) / 100;
// Update the count of
// candies
candies -= consume;
}
}
// Check if person 1 gets the
// good share of candies
return (taken >= good_share);
}
// Function to find minimum value of
// K such that the first person gets
// at least (N/(M+1)) candies
static void minimumK(ArrayList arr, int N,
int M)
{
// Find the minimum required value
// of candies for the first person
int good_share = (int)Math.ceil((N * 1.0)
/ ((M + 1) * 1.0));
int lo = 1, hi = N;
// Iterate until low is less
// than or equal to mid
while (lo < hi) {
// Find the value of mid
int mid = (lo + hi) / 2;
// Check for mid, whether it
// can be the possible value
// of K or not
if (check(mid, N, M, arr,
good_share)) {
// Update the value of hi
hi = mid;
}
// Otherwise, update the
// value of lo
else {
lo = mid + 1;
}
}
// Print the resultant minimum
// value of K
System.out.print(hi);
}
// Driver Code
public static void main(String[] args)
{
int N = 13, M = 1;
ArrayList arr = new ArrayList();
arr.add(50);
minimumK(arr, N, M);
}
}
// This code is contributed by avijitmondal1998.
输出:
3
时间复杂度: O(N 2 )
辅助空间: O(1)
高效方法:上述方法也可以通过使用二分搜索进行优化。请按照以下步骤解决问题:
- 找到(N/(M + 1))的值并将其存储在一个变量中,说好,因为这是A想吃的最少糖果。
- 初始化两个变量,比如低和高分别为1和N。
- 迭代直到low小于high并执行以下步骤:
- 找到mid的值为(low + high)/2 。
- 通过模拟上面提到的过程,找到人 A以K值为mid的最小糖果数量。
- 如果人 A拿走的糖果数量至少不错,则将high的值更新为mid 。否则,将low的值更新为(mid + 1) 。
- 完成上述步骤后,将high的值打印为K的结果最小值。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to check if the value of
// mid gives at least (N/(M + 1))
// candies or not
bool check(int K, int n, int m,
vector arr,
int good_share)
{
int candies = n, taken = 0;
while (candies > 0) {
// Candies taken by 1st
// person is minimum of K
// and candies left
taken += min(K, candies);
candies -= min(K, candies);
// Traverse the given array
for (int j = 0; j < m; j++) {
// Amount consumed by
// person j
int consume = (arr[j] * candies) / 100;
// Update the count of
// candies
candies -= consume;
}
}
// Check if person 1 gets the
// good share of candies
return (taken >= good_share);
}
// Function to find minimum value of
// K such that the first person gets
// at least (N/(M+1)) candies
void minimumK(vector &arr, int N,
int M)
{
// Find the minimum required value
// of candies for the first person
int good_share = ceil((N * 1.0)
/ ((M + 1) * 1.0));
int lo = 1, hi = N;
// Iterate until low is less
// than or equal to mid
while (lo < hi) {
// Find the value of mid
int mid = (lo + hi) / 2;
// Check for mid, whether it
// can be the possible value
// of K or not
if (check(mid, N, M, arr,
good_share)) {
// Update the value of hi
hi = mid;
}
// Otherwise, update the
// value of lo
else {
lo = mid + 1;
}
}
// Print the resultant minimum
// value of K
cout << hi;
}
// Driver Code
int main()
{
int N = 13, M = 1;
vector arr = { 50 };
minimumK(arr, N, M);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG {
// Function to check if the value of
// mid gives at least (N/(M + 1))
// candies or not
static boolean check(int K, int n, int m,
ArrayList arr,
int good_share)
{
int candies = n, taken = 0;
while (candies > 0) {
// Candies taken by 1st
// person is minimum of K
// and candies left
taken += Math.min(K, candies);
candies -= Math.min(K, candies);
// Traverse the given array
for (int j = 0; j < m; j++) {
// Amount consumed by
// person j
int consume = (arr.get(j) * candies) / 100;
// Update the count of
// candies
candies -= consume;
}
}
// Check if person 1 gets the
// good share of candies
return (taken >= good_share);
}
// Function to find minimum value of
// K such that the first person gets
// at least (N/(M+1)) candies
static void minimumK(ArrayList arr, int N,
int M)
{
// Find the minimum required value
// of candies for the first person
int good_share = (int)Math.ceil((N * 1.0)
/ ((M + 1) * 1.0));
int lo = 1, hi = N;
// Iterate until low is less
// than or equal to mid
while (lo < hi) {
// Find the value of mid
int mid = (lo + hi) / 2;
// Check for mid, whether it
// can be the possible value
// of K or not
if (check(mid, N, M, arr,
good_share)) {
// Update the value of hi
hi = mid;
}
// Otherwise, update the
// value of lo
else {
lo = mid + 1;
}
}
// Print the resultant minimum
// value of K
System.out.print(hi);
}
// Driver Code
public static void main(String[] args)
{
int N = 13, M = 1;
ArrayList arr = new ArrayList();
arr.add(50);
minimumK(arr, N, M);
}
}
// This code is contributed by avijitmondal1998.
时间复杂度: O(N * log N)
辅助空间: O(1)