公式

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:

  1. Choose the pipe with the largest effective length first (since it is added as-is)
  2. For the remaining pipes, add them if \(e_j - K > 0\) (i.e., \(e_j > K\)) (since adding them increases the total length)
  3. 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

  1. Compute the effective length \(e_i\) of each pipe.
  2. Sort the effective lengths in descending order.
  3. Select the first element (the largest effective length) and set \(\text{total} = e_0\).
  4. For each subsequent pipe, if \(e_i - K > 0\), add \(e_i - K\) to \(\text{total}\). Otherwise, stop.
  5. 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 long must 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.

投稿日時:
最終更新: