Given arr[] of weights, find the minimum boat capacity to ship all weights within d days.
- The items are loaded in the same order as their appearance.
- The total weight should not exceed the computed capacity on any day.
Examples:
Input: arr[] = [1, 2, 1], d = 2
Output: 3
Explanation: We can ship with boat capacity 3 in 2 days.
Day 1- 1, 2
Day 2- 1Input: arr[] = [9, 8, 10], d = 3
Output: 10
Explanation: We can ship with boat capacity 10 in 3 days.
Day 1- 9
Day 2- 8
Day 3- 10
Table of Content
[Naive Approach] Brute Force Approach - O(n * sum(arr)) Time and O(1) Space:
- The minimum possible capacity is the maximum weight, because every item must fit on some day.
- The maximum possible capacity is the sum of all weights, because then all items can be shipped in one day.
We try every capacity from max(arr) to sum(arr).
For each capacity, greedily load consecutive weights onto the current day until adding the next weight exceeds the capacity.
If the required number of days is at most d, that capacity is valid and is the minimum possible answer.
- Find the maximum weight in arr and use it as the initial capacity.
- For each capacity, traverse the weights in their given order and greedily load them into the current day.
- If adding a weight exceeds the current capacity, start a new day and load that weight there.
- Count the total number of days required for the current capacity.
- If the required days are at most d, return the current capacity.
- Otherwise, increase the capacity by 1 and repeat until a valid capacity is found.
#include <bits/stdc++.h>
using namespace std;
int leastWeightCapacity(vector<int> &arr, int d)
{
int n = arr.size();
// The capacity must be at least the maximum weight.
int capacity = *max_element(arr.begin(), arr.end());
// Try every possible capacity one by one.
while (true)
{
int days = 1;
int currentWeight = 0;
// Load weights in the given order.
for (int i = 0; i < n; i++)
{
// If adding the current weight exceeds
// the capacity, start a new day.
if (currentWeight + arr[i] > capacity)
{
days++;
currentWeight = 0;
}
// Add the current weight to the current day.
currentWeight += arr[i];
}
// If all weights can be shipped within d days,
// this is the minimum possible capacity.
if (days <= d)
return capacity;
// Otherwise, increase the capacity and try again.
capacity++;
}
}
int main()
{
vector<int> arr = {1, 2, 3, 4, 5, 6, 7};
int d = 5;
cout << leastWeightCapacity(arr, d) << endl;
return 0;
}
import java.util.*;
class GFG {
static int leastWeightCapacity(ArrayList<Integer> arr, int d)
{
int n = arr.size();
// The capacity must be at least the maximum weight.
int capacity = Collections.max(arr);
// Try every possible capacity one by one.
while (true) {
int days = 1;
int currentWeight = 0;
// Load weights in the given order.
for (int i = 0; i < n; i++) {
// If adding the current weight exceeds
// the capacity, start a new day.
if (currentWeight + arr.get(i) > capacity) {
days++;
currentWeight = 0;
}
// Add the current weight to the current
// day.
currentWeight += arr.get(i);
}
// If all weights can be shipped within d days,
// this is the minimum possible capacity.
if (days <= d)
return capacity;
// Otherwise, increase the capacity and try
// again.
capacity++;
}
}
public static void main(String[] args)
{
ArrayList<Integer> arr = new ArrayList<>(
Arrays.asList(1, 2, 3, 4, 5, 6, 7));
int d = 5;
System.out.println(leastWeightCapacity(arr, d));
}
}
def leastWeightCapacity(arr, d):
n = len(arr)
# The capacity must be at least the maximum weight.
capacity = max(arr)
# Try every possible capacity one by one.
while True:
days = 1
currentWeight = 0
# Load weights in the given order.
for i in range(n):
# If adding the current weight exceeds
# the capacity, start a new day.
if currentWeight + arr[i] > capacity:
days += 1
currentWeight = 0
# Add the current weight to the current day.
currentWeight += arr[i]
# If all weights can be shipped within d days,
# this is the minimum possible capacity.
if days <= d:
return capacity
# Otherwise, increase the capacity and try again.
capacity += 1
# Driver Code
if __name__ == "__main__":
arr = [1, 2, 3, 4, 5, 6, 7]
d = 5
print(leastWeightCapacity(arr, d))
using System;
class GFG {
static int leastWeightCapacity(int[] arr, int d)
{
int n = arr.Length;
// The capacity must be at least the maximum weight.
int capacity = arr[0];
for (int i = 1; i < n; i++)
capacity = Math.Max(capacity, arr[i]);
// Try every possible capacity one by one.
while (true) {
int days = 1;
int currentWeight = 0;
// Load weights in the given order.
for (int i = 0; i < n; i++) {
// If adding the current weight exceeds
// the capacity, start a new day.
if (currentWeight + arr[i] > capacity) {
days++;
currentWeight = 0;
}
// Add the current weight to the current
// day.
currentWeight += arr[i];
}
// If all weights can be shipped within d days,
// this is the minimum possible capacity.
if (days <= d)
return capacity;
// Otherwise, increase the capacity and try
// again.
capacity++;
}
}
public static void Main()
{
int[] arr = { 1, 2, 3, 4, 5, 6, 7 };
int d = 5;
Console.WriteLine(leastWeightCapacity(arr, d));
}
}
function leastWeightCapacity(arr, d)
{
let n = arr.length;
// The capacity must be at least the maximum weight.
let capacity = Math.max(...arr);
// Try every possible capacity one by one.
while (true) {
let days = 1;
let currentWeight = 0;
// Load weights in the given order.
for (let i = 0; i < n; i++) {
// If adding the current weight exceeds
// the capacity, start a new day.
if (currentWeight + arr[i] > capacity) {
days++;
currentWeight = 0;
}
// Add the current weight to the current day.
currentWeight += arr[i];
}
// If all weights can be shipped within d days,
// this is the minimum possible capacity.
if (days <= d)
return capacity;
// Otherwise, increase the capacity and try again.
capacity++;
}
}
// Driver Code
let arr = [ 1, 2, 3, 4, 5, 6, 7 ];
let d = 5;
console.log(leastWeightCapacity(arr, d));
Output
7
[Expected Approach] Using Binary Search - O(n * log(sum(arr))) Time and O(1) Space
The answer lies between max(arr) and sum(arr). we binary search this range.
For each mid capacity, we greedily calculate how many days are required. If it takes more than d days, the capacity is too small; otherwise, we try a smaller capacity.
- Set left = max(arr) and right = sum(arr), representing the minimum and maximum possible capacities.
- While left < right, calculate mid = left + (right - left) / 2.
- Traverse the array and greedily load weights in their given order; start a new day whenever the current capacity would be exceeded.
- If the required number of days is greater than d, increase the capacity by setting left = mid + 1.
- Otherwise, mid is feasible, so search for a smaller capacity by setting right = mid.
- When left == right, return left as the minimum required capacity.
#include <bits/stdc++.h>
using namespace std;
int leastWeightCapacity(vector<int> &arr, int d)
{
int n = arr.size();
// The capacity must be at least the maximum weight.
int left = *max_element(arr.begin(), arr.end());
// The capacity can be at most the sum of all weights.
int right = accumulate(arr.begin(), arr.end(), 0);
// Perform binary search on the possible capacity.
while (left < right)
{
// Calculate the middle capacity.
int mid = left + (right - left) / 2;
int days = 1;
int currentWeight = 0;
// Load weights in the given order.
for (int i = 0; i < n; i++)
{
// If adding the current weight exceeds the capacity,
// start a new day.
if (currentWeight + arr[i] > mid)
{
days++;
currentWeight = 0;
}
// Add the current weight to the current day.
currentWeight += arr[i];
}
// If more than d days are required, the capacity is too small.
if (days > d)
left = mid + 1;
// Otherwise, this capacity is feasible, so try a smaller one.
else
right = mid;
}
// left is the minimum capacity that can ship all weights within d days.
return left;
}
int main()
{
vector<int> arr = {1, 2, 3, 4, 5, 6, 7};
int d = 5;
cout << leastWeightCapacity(arr, d) << endl;
return 0;
}
import java.util.*;
class GFG {
static int leastWeightCapacity(ArrayList<Integer> arr, int d)
{
int n = arr.size();
// The capacity must be at least the maximum weight.
int left = Collections.max(arr);
// The capacity can be at most the sum of all
// weights.
int right = 0;
for (int weight : arr)
right += weight;
// Perform binary search on the possible capacity.
while (left < right) {
// Calculate the middle capacity.
int mid = left + (right - left) / 2;
int days = 1;
int currentWeight = 0;
// Load weights in the given order.
for (int i = 0; i < n; i++) {
// If adding the current weight exceeds the
// capacity, start a new day.
if (currentWeight + arr.get(i) > mid) {
days++;
currentWeight = 0;
}
// Add the current weight to the current
// day.
currentWeight += arr.get(i);
}
// If more than d days are required, the
// capacity is too small.
if (days > d)
left = mid + 1;
// Otherwise, this capacity is feasible, so try
// a smaller one.
else
right = mid;
}
// left is the minimum capacity that can ship all
// weights within d days.
return left;
}
public static void main(String[] args)
{
ArrayList<Integer> arr = new ArrayList<>(
Arrays.asList(1, 2, 3, 4, 5, 6, 7));
int d = 5;
System.out.println(leastWeightCapacity(arr, d));
}
}
def leastWeightCapacity(arr, d):
n = len(arr)
# The capacity must be at least the maximum weight.
left = max(arr)
# The capacity can be at most the sum of all weights.
right = sum(arr)
# Perform binary search on the possible capacity.
while left < right:
# Calculate the middle capacity.
mid = left + (right - left) // 2
days = 1
currentWeight = 0
# Load weights in the given order.
for i in range(n):
# If adding the current weight exceeds the capacity,
# start a new day.
if currentWeight + arr[i] > mid:
days += 1
currentWeight = 0
# Add the current weight to the current day.
currentWeight += arr[i]
# If more than d days are required, the capacity is too small.
if days > d:
left = mid + 1
# Otherwise, this capacity is feasible, so try a smaller one.
else:
right = mid
# left is the minimum capacity that can ship all weights within d days.
return left
# Driver Code
if __name__ == "__main__":
arr = [1, 2, 3, 4, 5, 6, 7]
d = 5
print(leastWeightCapacity(arr, d))
using System;
class GFG {
static int leastWeightCapacity(int[] arr, int d)
{
int n = arr.Length;
// The capacity must be at least the maximum weight.
int left = arr[0];
for (int i = 1; i < n; i++)
left = Math.Max(left, arr[i]);
// The capacity can be at most the sum of all
// weights.
int right = 0;
for (int i = 0; i < n; i++)
right += arr[i];
// Perform binary search on the possible capacity.
while (left < right) {
// Calculate the middle capacity.
int mid = left + (right - left) / 2;
int days = 1;
int currentWeight = 0;
// Load weights in the given order.
for (int i = 0; i < n; i++) {
// If adding the current weight exceeds the
// capacity, start a new day.
if (currentWeight + arr[i] > mid) {
days++;
currentWeight = 0;
}
// Add the current weight to the current
// day.
currentWeight += arr[i];
}
// If more than d days are required, the
// capacity is too small.
if (days > d)
left = mid + 1;
// Otherwise, this capacity is feasible, so try
// a smaller one.
else
right = mid;
}
// left is the minimum capacity that can ship all
// weights within d days.
return left;
}
public static void Main()
{
int[] arr = { 1, 2, 3, 4, 5, 6, 7 };
int d = 5;
Console.WriteLine(leastWeightCapacity(arr, d));
}
}
function leastWeightCapacity(arr, d)
{
let n = arr.length;
// The capacity must be at least the maximum weight.
let left = Math.max(...arr);
// The capacity can be at most the sum of all weights.
let right
= arr.reduce((sum, weight) => sum + weight, 0);
// Perform binary search on the possible capacity.
while (left < right) {
// Calculate the middle capacity.
let mid = left + Math.floor((right - left) / 2);
let days = 1;
let currentWeight = 0;
// Load weights in the given order.
for (let i = 0; i < n; i++) {
// If adding the current weight exceeds the
// capacity, start a new day.
if (currentWeight + arr[i] > mid) {
days++;
currentWeight = 0;
}
// Add the current weight to the current day.
currentWeight += arr[i];
}
// If more than d days are required, the capacity is
// too small.
if (days > d)
left = mid + 1;
// Otherwise, this capacity is feasible, so try a
// smaller one.
else
right = mid;
}
// left is the minimum capacity that can ship all
// weights within d days.
return left;
}
// Driver Code
let arr = [ 1, 2, 3, 4, 5, 6, 7 ];
let d = 5;
console.log(leastWeightCapacity(arr, d));
Output
7