B - パイプの接続 / Connecting Pipes 解説 by admin 印刷ページ
Claude 4.6 Opus (Thinking)Overview
This problem asks you to select one or more pipes from \(N\) pipes, connect them together, and maximize the length of the resulting pipe. Each pipe has an effective length, and when connecting two or more pipes, the length decreases by \(K\) at each connection point.
Analysis
Calculating Effective Lengths
First, we compute the effective length of each pipe.
- Non-rusted pipe (\(B_i = 0\)): effective length is \(A_i\)
- Rusted pipe (\(B_i = 1\)): effective length is \(\max(A_i - C, 0)\)
Decomposing the Formula for the Finished Pipe Length
When \(M\) pipes are selected, the length of the finished pipe is:
\[\sum_{j=1}^{M} e_j - (M - 1) \times K\]
where \(e_j\) is the effective length of each selected pipe. Rearranging this expression:
\[= e_1 + \sum_{j=2}^{M} (e_j - K)\]
In other words, the first pipe contributes its effective length as-is, and each subsequent pipe contributes its effective length minus \(K\) (i.e., \(e_j - K\)).
Greedy Strategy
From this decomposition, the optimal strategy becomes clear:
- Choose the pipe with the largest effective length first (since it is added as-is)
- For the remaining pipes, add them if \(e_j - K > 0\) (i.e., \(e_j > K\)) (since adding them increases the total length)
- Do not select pipes where \(e_j - K \leq 0\), as adding them would not increase (or would decrease) the length
If we sort the effective lengths in descending order, we can iterate from the beginning and keep adding pipes as long as \(e_j - K > 0\). Once we encounter \(e_j - K \leq 0\), all subsequent pipes will also satisfy this condition, so we can stop early.
Comparison with a Naive Approach
Trying all subsets would be \(O(2^N)\), which is far too slow for \(N \leq 10^5\). The greedy approach above only requires a single pass after sorting.
Algorithm
- Compute the effective length \(e_i\) of each pipe.
- Sort the effective lengths in descending order.
- Select the first element (the largest effective length) and set \(\text{total} = e_0\).
- For each subsequent pipe, if \(e_i - K > 0\), add \(e_i - K\) to \(\text{total}\). Otherwise, stop.
- If the final maximum value of \(\text{total}\) is at least \(D\), output it; otherwise, output \(-1\).
Concrete example: With \(N=3\), \(K=2\), \(C=1\) and effective lengths \([10, 5, 1]\) (already sorted in descending order):
- 1st pipe: \(\text{total} = 10\)
- 2nd pipe: \(5 - 2 = 3 > 0\) → \(\text{total} = 13\)
- 3rd pipe: \(1 - 2 = -1 \leq 0\) → do not add (stop)
The maximum length of the finished pipe is \(13\).
Complexity
- Time complexity: \(O(N \log N)\) (dominated by sorting)
- Space complexity: \(O(N)\) (array of effective lengths)
Implementation Notes
Since \(A_i\) and \(D\) can be large, the total value can become very large. In Python there is no concern about integer overflow, but in C++ and similar languages,
long longmust be used.The effective length of a rusted pipe is \(\max(A_i - C, 0)\); care must be taken to ensure it does not become negative.
Pipes with an effective length of \(0\) will automatically not be selected, since \(K \geq 1\) implies \(e_j - K < 0\).
Using
sys.stdin.buffer.read()for fast input reading is also effective for avoiding TLE when \(N\) is large.Source Code
import sys
def solve():
input_data = sys.stdin.buffer.read().split()
idx = 0
N = int(input_data[idx]); idx += 1
D = int(input_data[idx]); idx += 1
K = int(input_data[idx]); idx += 1
C = int(input_data[idx]); idx += 1
effective = []
for i in range(N):
A = int(input_data[idx]); idx += 1
B = int(input_data[idx]); idx += 1
if B == 1:
eff = max(A - C, 0)
else:
eff = A
effective.append(eff)
# When we select M pipes, the total length is:
# sum of effective lengths - (M-1)*K
# Adding a pipe with effective length e increases total by e - K (except for the first pipe).
# So we should:
# 1. Pick the pipe with the largest effective length first.
# 2. Then greedily add pipes where e - K > 0 (i.e., e > K), sorted by effective length descending.
effective.sort(reverse=True)
if N == 0:
print(-1)
return
# Start with the best single pipe
total = effective[0]
best = total
for i in range(1, N):
gain = effective[i] - K
if gain > 0:
total += gain
if total > best:
best = total
else:
break
if best >= D:
print(best)
else:
print(-1)
solve()
This editorial was generated by claude4.6opus-thinking.
投稿日時:
最終更新: