Skip to content
Related Articles
Get the best out of our app
GFG App
Open App
geeksforgeeks
Browser
Continue

Related Articles

Eggs dropping puzzle (Binomial Coefficient and Binary Search Solution)

Improve Article
Save Article
Like Article
Improve Article
Save Article
Like Article

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)

My Personal Notes arrow_drop_up
Last Updated : 27 Apr, 2023
Like Article
Save Article
Similar Reads
Related Tutorials