Topics

The problem asks us to find the minimum time for Takahashi to reach the ground. He has two actions:

  1. Increase gravity g by 1, which takes B seconds. Initially, g = 1.
  2. Jump from the building. The falling time is given by A / sqrt(g).

A and B are provided as inputs. We need to decide how many times Takahashi should increase the gravity to minimize the total time.

Idea

Let’s say Takahashi increases the gravity g_inc times. The total time will be:

Our goal is to minimize this function with respect to , where is a non-negative integer.

Approach 1: Using Calculus (Derivatives)

We can treat as a continuous variable and find the minimum of the function using derivatives. To find the minimum, we differentiate with respect to and set the derivative to zero:

Solving for :

Since must be an integer, we can take the ceiling of this value, or check the integers around this value to find the optimal integer .

Time Complexity:
Space Complexity:

Observe that the function is unimodal. For small values of , increasing reduces the falling time significantly, thus decreasing the total time. However, for large values of , the decrease in falling time becomes smaller, while the time to increase gravity keeps increasing. Thus, there exists a minimum value.

We can use ternary search to efficiently find the integer value of that minimizes within a certain range. Since the constraints are up to , a wide search range needs to be considered, but time complexity will still be logarithmic.

Time Complexity: where is the search range
Space Complexity:

Code

def func(a, b, g):
    # g should be an int, but for calc, convert to float
    g *= 1.0
    return b*g + a*((g+1)**(-0.5))
 
 
# Approach 1 (O(1) using derivates)
def solve_direct(a, b):
    g = -1 + (a/(2*b))**(2/3)
    g = math.ceil(g)
    return func(a, b, g)
 
 
# Approach 2 (log t.c using ternary search)
def ternary_search(low, high, f):
    low, high = int(low), int(high)
    while high - low > 3:
        m1 = low + (high - low) // 3
        m2 = high - (high - low) // 3
        if f(m1) < f(m2):
            high = m2
        else:
            low = m1
    return min(range(low, high+1), key=f)
 
 
def solve(a, b):
    low, high = 0, (a//b) + 5
    f = partial(func, a, b)
    g = ternary_search(low, high, f)
    return f(g)