The engineering team at an Amazon fulfillment cent...
Created on: July 8, 2025
Created on: July 8, 2025
The engineering team at an Amazon fulfillment center is optimizing n high-performance printers, where each printer i can print pages[i] number of pages.
Each printer can be in exactly one of three states:
• Idle (initial state)
• Operational
• Suspended
⸻
🔄 Activation & Suspension Rules:
• Printers start in an idle state and can be activated one by one.
• Once activated, a printer immediately prints its pages.
• However, suspensions can occur based on thresholds:
If there are at least x operational printers, any printer i such that threshold[i] ≤ x will get suspended immediately.
Suspended printers stop working and can no longer print.
⸻
🎯 Task:
Find the maximum total number of pages that can be printed by choosing the best order of activating the printers.
⸻
⚠️ Important Notes:
• Activating a printer with threshold[i] = x allows it to print pages[i] pages.
• But once there are x or more operational printers, any currently active printer j with threshold[j] ≤ x will get suspended after finishing its pages.
• Choosing the right activation order is crucial to maximize total printed pages before any suspensions occur.
long getPages(vector<int>& pages, vector<int>& threshold); • pages[i]: Number of pages printer i can print
• threshold[i]: Suspension threshold for printer i
• Returns:
• Maximum number of pages that can be printed before suspensions start
⸻
📌 Constraints:
• 1 \leq n \leq 2 \times 10^5 (varies – possibly smaller in actual tests)
• 1 \leq \text{pages}[i] \leq 10^9
• 1 \leq \text{threshold}[i] \leq n
⸻
Explanation:
• Activate printer 4 → prints 13 pages.
• Only 1 operational printer, so no suspensions.
• Then activate printer 1 → prints 2 more pages.
• Total = 13 + 2 = 15 pages.
🧪 Example 1: pages = [2, 6, 10, 13]
threshold = [2, 1, 1, 1] output - 15 Cpp code make sure u test ur output with exp output
pythondef getPages(pages, threshold): n=len(pages) jobs=sorted([(pages[i], threshold[i]-1) for i in range(n)], key=lambda x:-x[0]) parent=list(range(n)) def find(x): if x<0: return -1 if parent[x]==x: return x parent[x]=find(parent[x]) return parent[x] total=0 for p,d in jobs: slot=find(d) if slot>=0: total+=p parent[slot]=find(slot-1) return total print(getPages([2,6,10,13],[2,1,1,1]))
pythonprint(getPages([100,1,1],[3,1,1]))
Idea → reduce to classic “job-sequencing-with-deadlines”
What the rules really mean | Programming translation |
---|---|
• When k printers have been activated so far, the next printer we start must have threshold > k . | Each printer i must be scheduled no later than slot threshold[i] − 1 (0-based). |
• After that activation we have k + 1 operational printers, so all printers whose threshold ≤ k are “suspended forever” (and can never be started).<br>⇒ In every time-slot we may start at most one printer. | We can perform at most one “job” per slot. |
So every printer is a job
pages[i]
threshold[i] − 1
(latest slot in which it can be activated).Maximising pages printed before any suspension is exactly the classical problem:
“Pick the most profitable subset of jobs so that no more than one job is done in each time-slot ≤ its deadline.”
(pages, deadline)
with deadline = threshold − 1
.pages
.find(s)
returns the rightmost still-empty slot ≤ s, or −1 if none.slot = find(deadline)
.slot ≥ 0
, take it: add pages
to the answer and mark that slot as used by union(slot, slot–1)
.Because every printer is considered exactly once and each union-find operation is inverse-Ackermann time, the whole run-time is O(n log n)
for the initial sort plus near-linear afterwards; memory O(n)
.
cpp#include <bits/stdc++.h> using namespace std; struct DSU { vector<int> parent; DSU(int n) : parent(n) { iota(parent.begin(), parent.end(), 0); } int find(int x) { // returns right-most free slot ≤ x if (x < 0) return -1; return parent[x] == x ? x : parent[x] = find(parent[x]); } void occupy(int x) { // mark slot x as used parent[x] = find(x - 1); } }; long long getPages(vector<int>& pages, vector<int>& threshold) { const int n = pages.size(); vector<pair<int,int>> jobs; // {pages, deadline} jobs.reserve(n); for (int i = 0; i < n; ++i) jobs.emplace_back(pages[i], threshold[i] - 1); sort(jobs.begin(), jobs.end(), [](const auto& a, const auto& b){ return a.first > b.first; }); DSU dsu(n); // slots 0 … n-1 long long total = 0; for (auto [pg, dl] : jobs) { int slot = dsu.find(dl); if (slot >= 0) { total += pg; dsu.occupy(slot); } } return total; }
textpages = [ 2, 6, 10, 13 ] threshold = [ 2, 1, 1, 1 ] deadlines = [ 1, 0, 0, 0 ] // threshold − 1 sorted jobs: (13,0) (10,0) (6,0) (2,1) slot 0 free → take 13 total = 13 slot 0 now busy next job (10,0) → no free slot ≤0 (skip) next job ( 6,0) → no free slot ≤0 (skip) next job ( 2,1) → slot 1 free → take 2 total = 15
15
matches the expected answer.
The union-find procedure is the well-known optimal greedy for job sequencing:
We always try to schedule the most valuable remaining printer in the latest still-available slot it can fit; if no such slot exists, the printer can never be used without violating some other printer’s deadline, so skipping it cannot hurt any better solution.
Hence the algorithm yields the maximum total pages that can be printed before the first suspension event.