Open In App

Eggs dropping puzzle (Binomial Coefficient and Binary Search Solution)

Improve
Improve
Like Article
Like
Save
Share
Report

Given n eggs and k floors, find the minimum number of trials needed in worst case to find the floor below which all floors are safe. A floor is safe if dropping an egg from it does not break the egg. Please see n eggs and k floors. for complete statements

Example

Input : n = 2, k = 10
Output : 4
We first try from 4-th floor. Two cases arise,
(1) If egg breaks, we have one egg left so we
    need three more trials.
(2) If egg does not break, we try next from 7-th
    floor. Again two cases arise.
We can notice that if we choose 4th floor as first
floor, 7-th as next floor and 9 as next of next floor,
we never exceed more than 4 trials.

Input : n = 2. k = 100
Output : 14

We have discussed the problem for 2 eggs and k floors. We have also discussed a dynamic programming solution to find the solution. The dynamic programming solution is based on below recursive nature of the problem. Let us look at the discussed recursive formula from a different perspective.

How many floors we can cover with x trials? 
When we drop an egg, two cases arise. 

  1. If egg breaks, then we are left with x-1 trials and n-1 eggs.
  2. If egg does not break, then we are left with x-1 trials and n eggs
Let maxFloors(x, n) be the maximum number of floors 
that we can cover with x trials and n eggs. From above 
two cases, we can write.

maxFloors(x, n) = maxFloors(x-1, n-1) + maxFloors(x-1, n) + 1
For all x >= 1 and n >= 1

Base cases : 
We can't cover any floor with 0 trials or 0 eggs
maxFloors(0, n) = 0
maxFloors(x, 0) = 0

Since we need to cover k floors, 
maxFloors(x, n) >= k           ----------(1)

The above recurrence simplifies to following,
Refer this for proof.

maxFloors(x, n) = ∑xCi
                  1 <= i <= n   ----------(2)
Here C represents Binomial Coefficient.

From above two equations, we can say.
&Sum;xCj  >= k
1 <= i <= n
Basically we need to find minimum value of x
that satisfies above inequality. We can find
such x using Binary Search.

C++




// C++ program to find minimum
// number of trials in worst case.
#include <bits/stdc++.h>
 
using namespace std;
 
// Find sum of binomial coefficients xCi
// (where i varies from 1 to n).
int binomialCoeff(int x, int n, int k)
{
    int sum = 0, term = 1;
    for (int i = 1; i <= n; ++i) {
        term *= x - i + 1;
        term /= i;
        sum += term;
        if (sum > k)
            return sum;
    }
    return sum;
}
 
// Do binary search to find minimum
// number of trials in worst case.
int minTrials(int n, int k)
{
    // Initialize low and high as 1st
    // and last floors
    int low = 1, high = k;
 
    // Do binary search, for every mid,
    // find sum of binomial coefficients and
    // check if the sum is greater than k or not.
    while (low <= high) {
        int mid = (low + high) / 2;
        if (binomialCoeff(mid, n, k) < k)
            low = mid + 1;
        else
            high = mid;
    }
 
    return low;
}
 
/* Driver code*/
int main()
{
    cout << minTrials(2, 10);
    return 0;
}


Java




// Java program to find minimum
// number of trials in worst case.
class Geeks {
 
    // Find sum of binomial coefficients xCi
    // (where i varies from 1 to n). If the sum
    // becomes more than K
    static int binomialCoeff(int x, int n, int k)
    {
        int sum = 0, term = 1;
        for (int i = 1; i <= n && sum < k; ++i) {
            term *= x - i + 1;
            term /= i;
            sum += term;
        }
        return sum;
    }
 
    // Do binary search to find minimum
    // number of trials in worst case.
    static int minTrials(int n, int k)
    {
        // Initialize low and high as 1st
        // and last floors
        int low = 1, high = k;
 
        // Do binary search, for every mid,
        // find sum of binomial coefficients and
        // check if the sum is greater than k or not.
        while (low <= high) {
            int mid = (low + high) / 2;
            if (binomialCoeff(mid, n, k) < k)
                low = mid + 1;
            else
                high = mid;
        }
 
        return low;
    }
 
    /* Driver code*/
    public static void main(String args[])
    {
        System.out.println(minTrials(2, 10));
    }
}
 
// This code is contributed by ankita_saini


Python3




# Python3 program to find minimum
# number of trials in worst case.
 
# Find sum of binomial coefficients
# xCi (where i varies from 1 to n).
# If the sum becomes more than K
 
 
def binomialCoeff(x, n, k):
 
    sum = 0
    term = 1
    i = 1
    while(i <= n and sum < k):
        term *= x - i + 1
        term /= i
        sum += term
        i += 1
    return sum
 
# Do binary search to find minimum
# number of trials in worst case.
 
 
def minTrials(n, k):
 
    # Initialize low and high as
    # 1st and last floors
    low = 1
    high = k
 
    # Do binary search, for every
    # mid, find sum of binomial
    # coefficients and check if
    # the sum is greater than k or not.
    while (low <= high):
 
        mid = (low + high)//2
        if (binomialCoeff(mid, n, k) < k):
            low = mid + 1
        else:
            high = mid
 
    return low
 
 
# Driver Code
print(minTrials(2, 10))
 
# This code is contributed
# by mits


C#




// C# program to find minimum
// number of trials in worst case.
using System;
 
class Geeks
{
 
  // Find sum of binomial coefficients xCi
  // (where i varies from 1 to n). If the sum
  // becomes more than K
  static int binomialCoeff(int x, int n, int k)
  {
    int sum = 0, term = 1;
    for (int i = 1; i <= n && sum < k; ++i) {
      term *= x - i + 1;
      term /= i;
      sum += term;
    }
    return sum;
  }
 
  // Do binary search to find minimum
  // number of trials in worst case.
  static int minTrials(int n, int k)
  {
    // Initialize low and high as 1st
    // and last floors
    int low = 1, high = k;
 
    // Do binary search, for every mid,
    // find sum of binomial coefficients and
    // check if the sum is greater than k or not.
    while (low <= high) {
      int mid = (low + high) / 2;
      if (binomialCoeff(mid, n, k) < k)
        low = mid + 1;
      else
        high = mid;
    }
 
    return low;
  }
 
  /* Driver code*/
  public static void Main()
  {
    Console.WriteLine(minTrials(2, 10));
  }
}
 
// This code is contributed by Prajwal Kandekar


Javascript




<script>
 
// Javascript program to find minimum
// number of trials in worst case.
 
// Find sum of binomial coefficients xCi
// (where i varies from 1 to n). If the sum
// becomes more than K
function binomialCoeff(x, n, k)
{
    var sum = 0, term = 1;
    for(var i = 1; i <= n && sum < k; ++i)
    {
        term *= x - i + 1;
        term /= i;
        sum += term;
    }
    return sum;
}
 
// Do binary search to find minimum
// number of trials in worst case.
function minTrials(n, k)
{
     
    // Initialize low and high as 1st
    //and last floors
    var low = 1, high = k;
 
    // Do binary search, for every mid,
    // find sum of binomial coefficients and
    // check if the sum is greater than k or not.
    while (low < high)
    {
        var mid = parseInt((low + high) / 2);
        if (binomialCoeff(mid, n, k) < k)
            low = mid + 1;
        else
            high = mid;
    }
    return low;
}
 
// Driver code
document.write(minTrials(2, 10));
 
// This code is contributed by shivanisinghss2110
 
</script>


Output

4

Time Complexity : O(n Log k)
Auxiliary Space: O(1)

Another Approach:

The approach with O(n * k^2) has been discussed before, where dp[n][k] = 1 + max(dp[n – 1][i – 1], dp[n][k – i]) for i in 1…k. You checked all the possibilities in that approach.

Consider the problem in a different way:

dp[m][x] means that, given x eggs and m moves,
what is the maximum number of floors that can be checked

The dp equation is: dp[m][x] = 1 + dp[m - 1][x - 1] + dp[m - 1][x],
which means we take 1 move to a floor.
If egg breaks, then we can check dp[m - 1][x - 1] floors.
If egg doesn't break, then we can check dp[m - 1][x] floors.

C++




// C++ program to find minimum number of trials in worst
// case.
#include <bits/stdc++.h>
using namespace std;
 
int minTrials(int n, int k)
{
    // Initialize 2D of size (k+1) * (n+1).
    vector<vector<int> > dp(k + 1, vector<int>(n + 1, 0));
    int m = 0; // Number of moves
    while (dp[m][n] < k) {
        m++;
        for (int x = 1; x <= n; x++) {
            dp[m][x] = 1 + dp[m - 1][x - 1] + dp[m - 1][x];
        }
    }
    return m;
}
 
/* Driver code*/
int main()
{
    cout << minTrials(2, 10);
    return 0;
}
 
// This code is contributed by Arihant Jain (arihantjain01)


Java




// Java program to find minimum number of trials in worst
// case.
import java.util.*;
 
class GFG {
     
    // Returns minimum number of trials in worst case
    // with n eggs and k floors
    static int minTrials(int n, int k)
    {
        // Initialize 2D of size (k+1) * (n+1).
        int dp[][] = new int[k + 1][n + 1];
        int m = 0; // Number of moves
         
        while (dp[m][n] < k) {
            m++;
            for (int x = 1; x <= n; x++)
                dp[m][x] = 1 + dp[m - 1][x - 1]
                            + dp[m - 1][x];
        }
         
        return m;
    }
     
    // Driver code
    public static void main(String[] args)
    {
        System.out.println(minTrials(2, 10));
    }
}
//This code contributed by SRJ


C#




// C# program to find minimum number of trials in worst
// case.
using System;
class GFG {
    static int minTrials(int n, int k)
    {
       
        // Initialize 2D of size (k+1) * (n+1).
        int[, ] dp = new int[k + 1, n + 1];
        int m = 0; // Number of moves
        while (dp[m, n] < k) {
            m++;
            for (int x = 1; x <= n; x++) {
                dp[m, x]
                    = 1 + dp[m - 1, x - 1] + dp[m - 1, x];
            }
        }
        return m;
    }
    static void Main()
    {
      Console.Write(minTrials(2, 10));
    }
}
 
// This code is contributed by garg28harsh.


Javascript




// Javascript program to find minimum number of trials in worst
// case.
function minTrials( n, k)
{
    // Initialize 2D of size (k+1) * (n+1).
    let dp = new Array(k+1);
    for(let i=0;i<=k;i++)
        dp[i] = new Array(n+1);
    for(let i=0;i<=k;i++)
    for(let j=0;j<=n;j++)
       dp[i][j]=0;
    let m = 0; // Number of moves
    while (dp[m][n] < k) {
        m++;
        for (let x = 1; x <= n; x++) {
            dp[m][x] = 1 + dp[m - 1][x - 1] + dp[m - 1][x];
        }
    }
    return m;
}
    console.log(minTrials(2, 10));
  
 // This code is contributed by garg28harsh.


Python3




# Python program to find minimum number of trials in worst
# case.
def minTrials(n, k):
    # Initialize 2D array of size (k+1) * (n+1).
    dp = [[0 for j in range(n + 1)] for i in range(k + 1)]
    m = 0  # Number of moves
    while dp[m][n] < k:
        m += 1
        for x in range(1, n + 1):
            dp[m][x] = 1 + dp[m - 1][x - 1] + dp[m - 1][x]
    return m
 
# Driver code
if __name__ == '__main__':
    print(minTrials(2, 10))
 
# This code is contributed by Amit Mangal.


Output

4

Time Complexity: O(n*k)
Auxiliary Space: O(n*k)

Optimization to one-dimensional DP

The above solution can be optimized to one-dimensional DP as follows:

C++




// C++ program to find minimum number of trials in worst
// case.
#include <bits/stdc++.h>
using namespace std;
 
int minTrials(int n, int k)
{
    // Initialize array of size (n+1) and m as moves.
    int dp[n + 1] = { 0 }, m;
    for (m = 0; dp[n] < k; m++) {
        for (int x = n; x > 0; x--) {
            dp[x] += 1 + dp[x - 1];
        }
    }
    return m;
}
 
/* Driver code*/
int main()
{
    cout << minTrials(2, 10);
    return 0;
}
 
// This code is contributed by Arihant Jain (arihantjain01)


Java




// Java program to find minimum number of trials in worst
// case.
import java.util.*;
 
class GFG
{
  // Function to find minimum number of trials in worst
  // case.
  static int minTrials(int n, int k)
  {
    // Initialize array of size (n+1) and m as moves.
    int dp[] = new int[n + 1], m;
    for (m = 0; dp[n] < k; m++)
    {
      for (int x = n; x > 0; x--)
      {
        dp[x] += 1 + dp[x - 1];
      }
    }
    return m;
  }
 
  // Driver code
  public static void main(String[] args)
  {
    System.out.println(minTrials(2, 10));
  }
}
 
// This code is contributed by factworld78725.


Python3




# Python program to find minimum number of trials in worst case.
 
def minTrials(n, k):
    # Initialize list of size (n+1) and m as moves.
    dp = [0] * (n + 1)
    m = 0
    while dp[n] < k:
        m += 1
        for x in range(n, 0, -1):
            dp[x] += 1 + dp[x - 1]
    return m
 
# Code
print(minTrials(2, 10))
 
# This code is contributed by lokesh.


C#




// C# program to find minimum number of trials in worst
// case.
using System;
public class GFG {
 
  // Function to find minimum number of trials in worst
  // case.
  static int minTrials(int n, int k)
  {
    // Initialize array of size (n+1) and m as moves.
    int[] dp = new int[n + 1];
    int m = 0;
    for (; dp[n] < k; m++) {
      for (int x = n; x > 0; x--) {
        dp[x] += 1 + dp[x - 1];
      }
    }
    return m;
  }
 
  static public void Main()
  {
 
    // Code
    Console.WriteLine(minTrials(2, 10));
  }
}
 
// This code is contributed by karthik.


Javascript




function minTrials(n, k) {
    // Initialize list of size (n+1) and m as moves.
    let dp = new Array(n + 1).fill(0);
    let m = 0;
    while (dp[n] < k) {
        m += 1;
        for (let x = n; x > 0; x--) {
            dp[x] += 1 + dp[x - 1];
        }
    }
    return m;
}
 
// Driver code
console.log(minTrials(2, 10));
 
// This code is contributed by Amit Mangal.


Output

4

Complexity Analysis:

  • Time Complexity: O(n * log k)
  • Auxiliary Space: O(n)


Last Updated : 27 Apr, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads