找到最大高度以水平切割所有巧克力,以便至少保留 K 量
给定一个由N个巧克力棒高度组成的数组arr[] ,任务是找到对所有巧克力进行水平切割的最大高度,使得巧克力的剩余总量至少为 K。
例子:
Input: K = 7, arr[] = [15, 20, 8, 17]
Output: 15
Explanation:
Suppose a cut is made at height 8:
-> chocolate taken from 1st chocolate bar = 15 – 8 =7
-> chocolate taken from 2nd chocolate bar = 20 – 8 =12
-> chocolate taken from 3rd chocolate bar = 8 – 8 = 0
-> chocolate taken from 4th chocolate bar = 17 – 8 = 9
=> Total chocolate wasted = (7 + 12 + 0 + 9) – K = 28 – 7 = 21
Suppose a cut is made at height 15:
-> chocolate taken from 1st chocolate bar = 15 – 15 = 0
-> chocolate taken from 2nd chocolate bar = 20 – 15 = 5
-> 3rd chocolate bar wont be chosen as it is less than 15
-> chocolate taken from 4th chocolate bar = 17 – 15 = 2
=> Total chocolate wasted = (0 + 5 + 2) – K = 7 – 7 = 0
Therefore when we take chocolate of height 15 then chocolate wasted is minimum. Therefore 15 is the answer.
Input: K = 12, arr[] = [30, 25, 22, 17, 20]
Output: 21
Explanation:
After a cut at height 18, the chocolate removed is 25 and chocolate wastage is (25 – 12) = 13 units. But if the cut is made at height 21 is made then 14 units of chocolate is removed and the wastage is (14 – 12) = 2 which is the least, hence 21 is the answer
方法:给定的问题可以基于二分搜索来解决。
The idea is to perform the Binary Search over then range [0, max element of the array] and find that value in the range, say M, such that the sum of remaining chocolate after making the horizontal cut at M gives minimum difference with K.
请按照以下步骤解决给定的问题:
- 分别初始化两个变量,比如low和high为0和最大数组元素。
- 迭代直到low <= high并执行以下步骤:
- 找到mid的值为(low + high)/2 。
- 在中间高度为M进行水平切割后,找到剩余巧克力的总和。
- 如果M的值小于K ,则将high的值更新为(mid – 1) 。否则,将low的值更新为(mid + 1) 。
- 执行上述步骤后,打印与最终必须切割的最大高度一样高的值。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the sum of remaining
// chocolate after making the horizontal
// cut at height mid
int cal(vector arr, int mid)
{
// Stores the sum of chocolates
int chocolate = 0;
// Traverse the array arr[]
for (auto i : arr) {
// If the height is at least mid
if (i >= mid)
chocolate += i - mid;
}
// Return the possible sum
return chocolate;
}
// Function to find the maximum horizontal
// cut made to all the chocolates such that
// the sum of the remaining element is
// at least K
int maximumCut(vector arr, int K)
{
// Ranges of Binary Search
int low = 0;
int high = *max_element(arr.begin(), arr.end());
// Perform the Binary Search
while (low <= high) {
int mid = (low + high) / 2;
// Find the sum of removed after
// making cut at height mid
int chocolate = cal(arr, mid);
// If the chocolate removed is
// same as the chocolate needed
// then return the height
if (chocolate == K)
return mid;
// If the chocolate removed is
// less than chocolate needed
// then shift to the left range
else if (chocolate < K)
high = mid - 1;
// Otherwise, shift to the right
// range
else {
low = mid + 1;
if (mid > high)
high = mid;
}
}
// Return the possible cut
return high;
}
// Driver Code
int main()
{
int N = 4;
int K = 7;
vector arr{ 15, 20, 8, 17 };
cout << (maximumCut(arr, K));
}
// This code is contributed by ipg2016107.
Java
// Java program for the above approach
import java.util.*;
import java.util.Arrays;
class GFG {
// Function to find the sum of remaining
// chocolate after making the horizontal
// cut at height mid
static int cal(int arr[], int mid)
{
// Stores the sum of chocolates
int chocolate = 0;
// Traverse the array arr[]
for (int i = 0; i < arr.length; i++) {
// If the height is at least mid
if (arr[i] >= mid)
chocolate += arr[i] - mid;
}
// Return the possible sum
return chocolate;
}
// Function to find the maximum horizontal
// cut made to all the chocolates such that
// the sum of the remaining element is
// at least K
static int maximumCut(int arr[], int K)
{
// Ranges of Binary Search
int low = 0;
int high = Arrays.stream(arr).max().getAsInt();
// Perform the Binary Search
while (low <= high) {
int mid = (low + high) / 2;
// Find the sum of removed after
// making cut at height mid
int chocolate = cal(arr, mid);
// If the chocolate removed is
// same as the chocolate needed
// then return the height
if (chocolate == K)
return mid;
// If the chocolate removed is
// less than chocolate needed
// then shift to the left range
else if (chocolate < K)
high = mid - 1;
// Otherwise, shift to the right
// range
else {
low = mid + 1;
if (mid > high)
high = mid;
}
}
// Return the possible cut
return high;
}
// Driver Code
public static void main(String[] args)
{
int K = 7;
int arr[] = { 15, 20, 8, 17 };
System.out.println(maximumCut(arr, K));
}
}
// This code is contributed by ukasp.
Python3
# Python program for the above approach
# Function to find the sum of remaining
# chocolate after making the horizontal
# cut at height mid
def cal(arr, mid):
# Stores the sum of chocolates
chocolate = 0
# Traverse the array arr[]
for i in arr:
# If the height is at least mid
if i >= mid:
chocolate += i - mid
# Return the possible sum
return chocolate
# Function to find the maximum horizontal
# cut made to all the chocolates such that
# the sum of the remaining element is
# at least K
def maximumCut(arr, K):
# Ranges of Binary Search
low = 0
high = max(arr)
# Perform the Binary Search
while low <= high:
mid = (low + high) // 2
# Find the sum of removed after
# making cut at height mid
chocolate = cal(arr, mid)
# If the chocolate removed is
# same as the chocolate needed
# then return the height
if chocolate == K:
return mid
# If the chocolate removed is
# less than chocolate needed
# then shift to the left range
elif chocolate < K:
high = mid - 1
# Otherwise, shift to the right
# range
else:
low = mid + 1
if mid > high:
high = mid
# Return the possible cut
return high
# Driver Code
N, K = 4, 7
arr = [15, 20, 8, 17]
print(maximumCut(arr, K))
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
using System.Linq;
class GFG {
// Function to find the sum of remaining
// chocolate after making the horizontal
// cut at height mid
static int cal(List arr, int mid)
{
// Stores the sum of chocolates
int chocolate = 0;
// Traverse the array arr[]
foreach(int i in arr)
{
// If the height is at least mid
if (i >= mid)
chocolate += i - mid;
}
// Return the possible sum
return chocolate;
}
// Function to find the maximum horizontal
// cut made to all the chocolates such that
// the sum of the remaining element is
// at least K
static int maximumCut(List arr, int K)
{
// Ranges of Binary Search
int low = 0;
int high = arr.Max();
// Perform the Binary Search
while (low <= high) {
int mid = (low + high) / 2;
// Find the sum of removed after
// making cut at height mid
int chocolate = cal(arr, mid);
// If the chocolate removed is
// same as the chocolate needed
// then return the height
if (chocolate == K)
return mid;
// If the chocolate removed is
// less than chocolate needed
// then shift to the left range
else if (chocolate < K)
high = mid - 1;
// Otherwise, shift to the right
// range
else {
low = mid + 1;
if (mid > high)
high = mid;
}
}
// Return the possible cut
return high;
}
// Driver Code
public static void Main()
{
int K = 7;
List arr = new List() { 15, 20, 8, 17 };
Console.Write(maximumCut(arr, K));
}
}
// This code is contributed by SURENDRA_GANGWAR.
Javascript
15
时间复杂度: O(N*log N)
辅助空间: O(1)