D - プリンターの割り当て / Printer Assignment 解説 by admin
gpt-5.5-highOverview
Assign each print request to a printer that can handle it, and find the minimum time at which all requests are completed.
We determine “Can all requests be processed by a given time \(x\)?” and use binary search on the answer based on this decision.
Analysis
Printer \(i\) always takes \(T_i\) to process one request.
Therefore, the number of requests printer \(i\) can process by time \(x\) is
\( \left\lfloor \frac{x}{T_i} \right\rfloor \)
requests.
In other words, when time \(x\) is fixed, the problem can be rephrased as follows:
- Printer \(i\) can process at most \( \left\lfloor \frac{x}{T_i} \right\rfloor \) requests
- However, a request with \(P_j\) pages can only be assigned to a printer where \(W_i \geq P_j\)
- Can all requests be assigned?
The key insight here is that if processing is possible by time \(x\), then it is always possible by a longer time \(x+1\) or more.
Therefore, we can binary search on the answer.
Decision Method
Sort the requests in decreasing order of page count, and sort the printers in decreasing order of maximum page capacity \(W_i\).
Requests with more pages have fewer printers that can handle them.
Therefore, it is natural to greedily assign larger requests first to printers with higher capacity.
For example, suppose at a given time \(x\), the processing capacities of the printers are as follows:
| Printer | Max Pages \(W_i\) | Processing Capacity |
|---|---|---|
| A | 10 | 1 |
| B | 8 | 2 |
| C | 4 | 1 |
If the page counts of the requests are
\(9, 8, 5, 4\)
then we can assign:
- \(9\) to A
- \(8, 5\) to B
- \(4\) to C
On the other hand, if we consider printers with smaller maximum page capacity first, larger requests may become unassignable later.
Therefore, it is important to “process larger requests using printers with larger \(W_i\) first.”
Why a Naive Approach Is Difficult
Searching for available printers for each request or simulating the actual schedule would be too slow since \(N+M \leq 2 \times 10^5\).
Also, trying all possible assignments causes combinatorial explosion.
Therefore, we take the following approach:
- Binary search on the answer
- For a fixed time \(x\), greedily determine whether all requests can be assigned
Algorithm
First, if there exists a request that no printer can handle, it is impossible.
Specifically, if
\( \max P_j > \max W_i \)
then there is no printer that can process that request, so the answer is \(-1\).
Otherwise, we binary search on the answer.
Decision Function ok(x)
Determines whether all requests can be processed by time \(x\).
- Sort requests in decreasing order of page count
- Sort printers in decreasing order of \(W_i\)
- Maintain an index
idxpointing to the largest unassigned request - For each printer:
- The number of requests this printer can process by time \(x\) is \(x // T_i\)
- If the current largest unprocessed request cannot be handled by this printer, then no subsequent printer can handle it either, so it is impossible
- If it can be handled, assign as many requests as possible to this printer
- If all requests are assigned, it is possible
The following part of the code performs the decision:
def ok(x):
idx = 0
for w, t in ps:
if idx >= m:
return True
cap = x // t
if cap:
if js[idx] > w:
return False
idx += cap
if idx >= m:
return True
return False
Here, js is the array of requests sorted in decreasing order of page count.
ps is the array of printers sorted in decreasing order of \(W_i\).
If js[idx] > w, the current largest remaining request cannot be processed by this printer.
Furthermore, since all subsequent printers have \(W_i\) that is equal or smaller, no printer can process this request anymore.
Therefore, we can determine it is impossible.
Binary Search
As an upper bound for the answer, consider the case where the fastest printer capable of handling the request with the most pages processes all requests by itself.
hi = min(t for w, t in printers if w >= max_p) * M
This value is always an achievable time.
Then:
- If
ok(mid)is true, it might be possible in less time, so sethi = mid - If false, there is not enough time, so set
lo = mid
and perform binary search.
Ultimately, hi is the answer.
Complexity
- Time complexity: \(O(N \log N + M \log M + N \log (M \max T_i))\)
- Space complexity: \(O(N + M)\)
The number of binary search iterations is at most about \(50\).
Each decision only iterates through the printers once, so it is \(O(N)\).
Implementation Notes
Requests are sorted in decreasing order of page count with
jobs.sort(reverse=True).Printers are also sorted in decreasing order of \(W_i\) with
printers.sort(reverse=True).The answer can be as large as \(10^9 \times 2 \times 10^5 = 2 \times 10^{14}\), so 64-bit integers are required.
- In Python, there is no need to worry about integer overflow.
In the decision function, instead of assigning requests one by one, we advance by
idx += capto process them in bulk for efficiency.Source Code
import sys
def main():
data = list(map(int, sys.stdin.buffer.read().split()))
it = iter(data)
N = next(it)
M = next(it)
printers = []
max_w = 0
for _ in range(N):
w = next(it)
t = next(it)
printers.append((w, t))
if w > max_w:
max_w = w
jobs = [next(it) for _ in range(M)]
max_p = max(jobs)
if max_p > max_w:
print(-1)
return
jobs.sort(reverse=True)
printers.sort(reverse=True)
hi = min(t for w, t in printers if w >= max_p) * M
lo = 0
js = jobs
ps = printers
m = M
def ok(x):
idx = 0
for w, t in ps:
if idx >= m:
return True
cap = x // t
if cap:
if js[idx] > w:
return False
idx += cap
if idx >= m:
return True
return False
while lo + 1 < hi:
mid = (lo + hi) // 2
if ok(mid):
hi = mid
else:
lo = mid
print(hi)
if __name__ == "__main__":
main()
This editorial was generated by gpt-5.5-high.
投稿日時:
最終更新: