Official

D - 荷物の配達 / Package Delivery Editorial by admin

DeepSeek V3

Overview

This is a problem where you need to select delivery requests while satisfying a weight limit for packages and a required net profit, and among such selections, find the one that minimizes the number of selected requests.

Analysis

This problem asks us to find the minimum number of requests to select among all selections that satisfy two constraints: “the total weight of packages is at most \(S\)” and “the total net profit is at least \(T\).” Since each request has two choices — “select / don’t select” — this can be viewed as a variant of the subset sum problem.

A naive exhaustive search would examine \(2^N\) possibilities (since \(N \leq 50\), we have \(2^{50} \approx 10^{15}\)), which is far too large to be practical. Therefore, we consider solving this efficiently using dynamic programming.

Algorithm

We construct the following DP table using dynamic programming: - dp[count][s]: the maximum net profit when exactly count requests are selected and the total weight of packages is s

DP table initialization: - dp[0][0] = 0 (net profit is 0 when 0 requests are selected) - All other entries are initialized to a sufficiently small value (\(-10^9\))

For each request, we perform transitions from the current state for the case of “selecting that request.” We loop backwards over the number of selected requests count and weight s to avoid selecting the same request more than once.

After computing all DP states, we find the minimum count among all states satisfying dp[count][s] >= T and s <= S. If no such state exists, we output -1.

Complexity

  • Time complexity: \(O(N^2 \cdot S)\)
    • A triple loop over the number of requests \(N\), the number of selected requests \(N\), and the weight \(S\)
  • Space complexity: \(O(N \cdot S)\)
    • The DP table has size \(N \times S\)

Implementation Notes

  • The DP table is a 2D array managed by [number of selected requests][total weight]

  • Loop backwards to avoid selecting the same item more than once

  • Initial values are set to a sufficiently small negative value (to represent unreachable states)

  • Finally, search for the minimum number of requests that satisfies the conditions

    Source Code

def main():
    import sys
    data = sys.stdin.read().split()
    if not data:
        print(-1)
        return
        
    n = int(data[0]); S = int(data[1]); T_req = int(data[2])
    P = []; C = []; W = []
    index = 3
    for i in range(n):
        p = int(data[index]); c = int(data[index+1]); w = int(data[index+2])
        index += 3
        P.append(p)
        C.append(c)
        W.append(w)
        
    profits = [P[i] - C[i] for i in range(n)]
    
    INF = float('inf')
    min_items = INF
    
    dp = [[-10**9] * (S+1) for _ in range(n+1)]
    dp[0][0] = 0
    
    for i in range(n):
        w_i = W[i]
        profit_i = profits[i]
        for count in range(i, -1, -1):
            for s in range(S, -1, -1):
                if dp[count][s] != -10**9:
                    new_s = s + w_i
                    if new_s <= S:
                        new_profit = dp[count][s] + profit_i
                        if new_profit > dp[count+1][new_s]:
                            dp[count+1][new_s] = new_profit
                            
    for count in range(n+1):
        for s in range(S+1):
            if dp[count][s] >= T_req:
                if count < min_items:
                    min_items = count
                    
    if min_items != INF:
        print(min_items)
    else:
        print(-1)

if __name__ == "__main__":
    main()

This editorial was generated by deepseekv3.

posted:
last update: