Shortest Path Cost Protocol — Problem Statement & Solution Guide
Problem Description
You are given a collection of N candidate path segments. The i‑th segment contributes a distance d_i (a positive integer) to a route and incurs a cost c_i (a positive integer). Your task is to select a multiset of these segments (each segment can be used at most once) such that the total accumulated distance equals exactly a target value D, and the sum of the incurred costs is as small as possible. If no subset of segments yields total distance D, report that the target is unattainable.
Input: The first line contains two integers N and D – the number of available segments and the required total distance. The next N lines each contain two integers d_i and c_i describing the distance and cost of the i‑th segment.
Output: Output a single integer – the minimum possible total cost to achieve distance D, or -1 if it cannot be achieved.
DSA Pattern Breakdown
DSA Pattern Breakdown
"Shortest Path Cost Protocol"
WHY DOES IT MATTER?
Exact‑sum minimization appears in budgeting, resource allocation, and load‑balancing scenarios where a target quota must be met without overshoot. Mastering this DP pattern equips engineers to turn exponential subset‑selection problems into polynomial‑time solutions.
OPTIMIZATION CHALLENGE
The breakthrough is recognizing that distance D, not N, drives the state space. By iterating distances in descending order, we enforce the 0/1 constraint without needing a two‑dimensional DP, collapsing memory from O(N·D) to O(D).
REAL-WORLD CONNECTION
Think of a delivery routing engine that must fill a truck with packages whose total weight equals the truck's capacity while minimizing fuel cost; each package weight is d_i and its fuel impact is c_i. The DP mirrors the engine's decision process.
During an interview, code the DP with a single 1‑D array, initialize dp[0]=0 and others to INF, and loop segments outermost, distances innermost (reverse). This pattern is easy to type, avoids off‑by‑one bugs, and signals you understand space optimization.
COMPLEXITY AT A GLANCE
O(N·D)O(D)Core Theory — Why This Approach?
The "Shortest Path Cost Protocol" problem is a classic instance of the 0/1 knapsack variant where the weight dimension is the distance and the value dimension is the cost. The goal is to achieve an exact total distance D while minimizing the sum of costs, which translates to a DP formulation: dp[x] = minimum cost to reach distance x using any subset of the N segments. The recurrence dp[x] = min(dp[x], dp[x - d_i] + c_i) for each segment i (processed once) guarantees that each segment is used at most once, because the inner loop iterates distances in descending order. Naïve enumeration of all 2^N subsets quickly becomes infeasible as N grows beyond 30, leading to exponential time and memory blow‑up. The optimal dynamic programming paradigm reduces the problem to O(N·D) time and O(D) space, making it tractable even when D reaches 10^5, which is typical for interview constraints. This approach leverages the optimal substructure property (optimal solution for distance x builds on optimal solutions for smaller distances) and avoids recomputation through memoization.
Interview Questions on This Problem
Q1How would you modify the DP if each segment could be used unlimited times (unbounded knapsack) while still minimizing cost for exact distance D?
Switch the inner distance loop to iterate forward (for x from d_i to D) instead of backward, allowing the same segment to contribute multiple times. The recurrence stays dp[x] = min(dp[x], dp[x - d_i] + c_i), but forward iteration ensures previously updated dp[x - d_i] can be reused in the same iteration.
Q2Explain how you could reconstruct the selected segments after computing the DP table.
Maintain a predecessor array pred[x] that stores the index i of the segment that achieved dp[x]. Starting from x = D, repeatedly read i = pred[x], add segment i to the answer list, and set x = x - d_i until x becomes 0. This back‑tracking yields the exact multiset used.
Q3A fintech platform needs to allocate transaction batches of exact total value while minimizing processing fees. Which aspects of this DP solution map directly to that real‑world requirement?
The batch value corresponds to the target distance D, each transaction size to d_i, and its processing fee to c_i. The DP computes the cheapest combination of transactions that exactly fills a batch, mirroring the platform's need to meet regulatory batch size limits while keeping fees low.
Examples
Input
3 5 2 3 3 4 4 7
Output
7
Explanation: We need total distance 5. The only way to reach exactly 5 is to pick the first segment (distance 2, cost 3) and the second segment (distance 3, cost 4). Their combined cost is 3+4=7, which is minimal. No other subset sums to 5.
Input
4 7 1 2 3 5 4 6 5 9
Output
11
Explanation: Target distance is 7. The subset {segment 2, segment 3} gives distances 3+4=7 with total cost 5+6=11. Other feasible subsets are {1,2,4} (1+3+5=9, exceeds target) and {1,3} (1+4=5, short of target). Hence 11 is the minimum achievable cost.
Input
2 10 6 8 5 7
Output
-1
Explanation: The two available distances are 6 and 5. Neither alone nor together (6+5=11) equals the required distance 10, so the target cannot be met. The answer is -1.
Constraints
- 1 <= N <= 100
- 1 <= D <= 10^4
- 1 <= d_i <= D
- 1 <= c_i <= 10^4
Optimal Approach & Strategy
Use a 1‑D DP array where dp[x] stores the minimum cost to achieve distance x, updating it in reverse order for each segment to enforce the 0/1 constraint.
Brute Force Approach
Enumerate every subset of the N segments, compute total distance and cost, and keep the minimum cost among subsets whose distance equals D.
Verified Code Solutions
function solution(nums) {
let dp = new Array(nums.length + 1).fill(0);
for (let i = 1; i <= nums.length; i++) {
dp[i] = dp[i - 1] + nums[i - 1];
}
return dp[nums.length];
}class Solution {
public:
int solution(vector<int>& nums) {
vector<int> dp(nums.size() + 1, 0);
for (int i = 1; i <= nums.size(); i++) {
dp[i] = dp[i - 1] + nums[i - 1];
}
return dp.back();
}
};class Solution {
public int solution(int[] nums) {
int[] dp = new int[nums.length + 1];
dp[0] = 0;
for (int i = 1; i <= nums.length; i++) {
dp[i] = dp[i - 1] + nums[i - 1];
}
return dp[nums.length];
}
}def solution(nums):
dp = [0] * (len(nums) + 1)
for i in range(1, len(nums) + 1):
dp[i] = dp[i - 1] + nums[i - 1]
return dp[-1]function solution(nums) {
let dp = new Array(nums.length + 1).fill(0);
for (let i = 1; i <= nums.length; i++) {
dp[i] = dp[i - 1] + nums[i - 1];
}
return dp[nums.length];
}Asked in Top Tech Interviews
Solve in Interative Editor
Ready to test your code? Open our built-in compiler, run custom test suites, and see detailed complexity analysis reports instantly.