PROBLEM LINK:
Practice
Contest: Division 1
Contest: Division 2
Contest: Division 3
Contest: Division 4
Author: raysh07
Tester: sushil2006
Editorialist: iceknight1093
DIFFICULTY:
Simple
PREREQUISITES:
Binary search
PROBLEM:
There are N types of food, the i-th has A_i units available.
M friends want to go on an adventure.
Find the maximum possible number of days they can adventure, given that:
- Each friend eats one unit of food everyday.
- A friend must eat the same type of food on all days.
EXPLANATION:
Let’s solve a slightly more restricted version of the problem first: suppose we also knew the value D denoting the number of days the adventure must go on for; and we only need to check if there’s enough food to do this.
Consider the i-th food item.
If k people want to eat it during the adventure, we’d need (at least) k\cdot D units of it available to satisfy them all, since each person eats one unit per day.
Thus, k\cdot D \le A_i must hold.
The largest valid k is exactly \left\lfloor \frac{A_i}{D} \right\rfloor, where \left\lfloor x \right\rfloor denotes the value of x rounded down to the nearest integer (a.k.a. the floor of x.)
So, with a fixed D, the maximum number of people who can possibly be satisfied equals
If this quantity is \ge M then all M friends will be able to adventure for D days.
If this quantity is \lt M then there’s not enough food under the given constraints.
From above, we’re able to perform the check for a given value of D in \mathcal{O}(N) time.
Now, observe that if it’s possible to adventure for D days, then it’s certainly possible to adventure for \le D days as well.
On the other hand, if it’s not possible to adventure for D days, then it’s impossible to adventure for \gt D days.
This monotonicity allows us to binary search for the largest value of D that passes the check.
For the bounds of the binary search: 0 is a natural lower bound, while a trivial upper bound is \text{sum}(A).
Each check is done in \mathcal{O}(N) time, so we obtain an algorithm that’s \mathcal{O}(N\log (\operatorname{sum}(A))), which is easily fast enough.
TIME COMPLEXITY:
\mathcal{O}(N\log (\operatorname{sum}(A))) per testcase.
CODE:
Editorialist's code (PyPy3)
n, m = map(int, input().split())
a = list(map(int, input().split()))
lo, hi = 0, 10**9
while lo < hi:
mid = (lo + hi + 1)//2
have = 0
for x in a: have += x // mid
if have >= m: lo = mid
else: hi = mid-1
print(lo)