Topics
The problem asks us to find the minimum time for Takahashi to reach the ground. He has two actions:
- Increase gravity
g
by 1, which takesB
seconds. Initially,g = 1
. - 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:
Approach 2: Ternary Search
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)