Capacity To Ship Packages Within D Days

Problem Statement

 
A conveyor belt has packages that must be shipped from one port to another within D days. The i-th package on the conveyor belt has a weight of weights[i]. Each day, we load the ship with packages on the conveyor belt (in the order given by weights). We may not load more weight than the maximum weight capacity of the ship. Return the least weight capacity of the ship that will result in all the packages on the conveyor belt being shipped within D days in the given order of the packages.
 
Let's take one example. The weights of the packages are [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] and the minimum number of days (D) is 5. Then, the minimum weight capacity of the ship will be 15 because, on the 1st day the packages [ 1, 2, 3, 4, 5 ] will be shipped and similarly on the 2nd day [ 6, 7 ], on the 3rd day [ 8 ] 4th day: [ 9 ] 5th day: [ 10 ]. We have another solution for the same example. That's 14 by splitting the packages into parts like (2, 3, 4, 5), (1, 6, 7), (8), (9), (10) but it's not allowed since the order of the packages also needs to be maintained. Given below are some more examples for the leetcode problem,
  1. static void Main(string[] args)  
  2. {  
  3.     int result = ShipWithinDays(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, D: 5);  
  4.     // example 1 : result = 15  
  5.     result = ShipWithinDays(new int[] { 3, 2, 2, 4, 1, 4 }, D: 3);  
  6.     // example 2 : result = 6  
  7.     result = ShipWithinDays(new int[] { 1, 2, 3, 1, 1 }, D : 4);  
  8.     // example 3 : result = 3  
  9. }  

Solution

 
Our approach towards the problem is using binary search over all possible capacities of the ship for the minimum number of days. Let's discuss the algorithm in simple terms, 
  1. Finding the maximum weight (i.e., shipping all the packages in one day or sum of all wieghts) and minimum weight (i.e., shipping only one package in one day or maximum of the weights) for the ship to carry in a day.
  2. Start guessing for the minimum ship capacity for each day by taking the average of the maximum and minimum weight.
  3. Keep incrementing the minimum weight if the number of days calculated and D is same or else decrement the maximum weight.
  4. Store the best guess and as soon as the minimum becomes greater than or equal to maximum weight. 
 Here is the C# code for the algorithm given above,
  1. public static int ShipWithinDays(int[] weights, int D)  
  2. {  
  3.     int minimumWeight = weights.Max();  
  4.     int maximumWeight = weights.Sum();  
  5.   
  6.     if (TotalDaysToShip(weights, minimumWeight) <= D)  
  7.         return minimumWeight;  
  8.       
  9.     int currentGuess;  
  10.     int bestGuess = -1;  
  11.   
  12.     while (minimumWeight <= maximumWeight)  
  13.     {  
  14.         currentGuess = (maximumWeight + minimumWeight) / 2;  
  15.         if (TotalDaysToShip(weights, currentGuess) <= D)  
  16.         {  
  17.             bestGuess = currentGuess;  
  18.             maximumWeight = currentGuess - 1;  
  19.         }  
  20.         else  
  21.             minimumWeight = currentGuess + 1;  
  22.     }  
  23.     return bestGuess;  
  24. }  
  25. private static int TotalDaysToShip(int[] weights, int capacity)  
  26. {  
  27.     int days = 1;  
  28.     int currentShip = 0;  
  29.     foreach (int weight in weights)  
  30.     {  
  31.         if (currentShip + weight > capacity)  
  32.         {  
  33.             currentShip = 0;  
  34.             days++;  
  35.         }  
  36.         currentShip += weight;  
  37.     }  
  38.     return days;  
  39. }