Container Distribution Count — Problem Statement & Solution Guide

RecursionMediumMixed
TimeO(n*m*W*C)
|
SpaceO(m*W*C)

Quick Answer & Algorithm Key Takeaway

Master coding challenges related to Recursion and solve the Container Distribution Count problem optimally.

TopicRecursion
PatternMixed
TimeO(n*m*W*C)
SpaceO(m*W*C)

Problem Description

You are given two integer arrays: capacities, where capacities[i] denotes the weight of the i‑th container, and ships, where ships[j] denotes both the maximum total weight a ship can carry and the maximum number of containers it may hold. Every container must be placed on exactly one ship. A placement is valid if, for each ship, the sum of the weights of containers assigned to it does not exceed ships[j] **and** the count of containers assigned to it does not exceed ships[j]. Compute the number of distinct valid assignments. If no assignment satisfies the constraints, return 0.

DSA Pattern Breakdown

DSA Pattern Breakdown

"Container Distribution Count"

medium

WHY DOES IT MATTER?

Multi‑constraint partitioning appears in load‑balancing, resource scheduling, and bin‑packing where both size and cardinality limits exist; mastering this pattern lets engineers design scalable allocators.

OPTIMIZATION CHALLENGE

The breakthrough is recognizing that the state can be compressed to the remaining weight and slot count for the active ship; this collapses an exponential tree into a DP table whose dimensions are bounded by the ship limits, not by the number of containers.

REAL-WORLD CONNECTION

Think of a warehouse where each truck can carry only a certain total weight and a limited number of pallets – the algorithm decides how many loading configurations are feasible.

When coding, first sort ships by weight limit (or container limit) to prune early, and always store the memo key as a string or tuple to guarantee O(1) look‑ups; also use long integers for the count because the answer can be huge.

COMPLEXITY AT A GLANCE

⏱ Time:O(n*m*W*C)
💾 Space:O(m*W*C)

Core Theory — Why This Approach?

The problem is a constrained partitioning task where each ship imposes two simultaneous caps: a weight budget and a container count budget. A naive enumeration would try every possible assignment of n containers to m ships, leading to O(m^n) blow‑up. The optimal paradigm treats the decision as a recursive state defined by the current container index and the remaining resources of the current ship, then moves to the next ship when either limit is exhausted. By memoizing the tuple (pos, shipIdx, remainingWeight, remainingSlots) we collapse overlapping sub‑problems, turning exponential search into a pseudo‑polynomial DP that runs in O(n · m · W · C) where W is the maximum ship weight limit and C the maximum container count per ship. This is essentially a multi‑dimensional knapsack counting problem solved via recursion with memoization (top‑down DP).

Interview Questions on This Problem

Q1How would you count the number of ways to assign containers to ships when each ship has both a weight limit and a container‑count limit?

Model the process as a recursion over containers. For each container you either place it on the current ship (if weight+count constraints allow) or skip to the next ship. Memoize the state (i, shipIdx, remainingWeight, remainingSlots) to avoid recomputation, yielding a DP solution.

Q2Why does a simple backtracking solution time out for n=20 and m=10 with weight limits up to 10^4?

Backtracking explores every subset of containers for each ship, which is O(m^n). Even with pruning, the search space remains exponential because the same sub‑problem (e.g., remaining containers with identical resource leftovers) is revisited many times. Without memoization the runtime explodes.

Q3Can the container‑distribution problem be reduced to a classic DP formulation? If so, which one and how?

Yes, it reduces to a two‑dimensional knapsack counting DP. Treat each ship as a knapsack with capacity (weightLimit, countLimit). Iterate ships and update dp[weight][count] = number of ways to fill that ship, then combine results across ships, which is equivalent to the memoized recursion.

Examples

Example 1

Input

{"capacities":[1,2],"ships":[3,2]}

Output

3

Explanation: All containers must be placed. Valid assignments: (a) both containers on ship 0 (weight 3 ≤3, count 2 ≤3); (b) container 1 on ship 0 and container 2 on ship 1 (weights 1≤3,2≤2, counts 1≤3,1≤2); (c) container 2 on ship 0 and container 1 on ship 1 (weights 2≤3,1≤2, counts 1≤3,1≤2). No other distribution respects both limits, so the answer is 3.

Example 2

Input

{"capacities":[4,4,4],"ships":[5,5]}

Output

0

Explanation: Each ship can carry at most weight 5 and at most 5 containers. A single container weighs 4, so a ship can hold at most one container (two would exceed the weight limit). With three containers and only two ships, it is impossible to place every container, hence 0 ways.

Example 3

Input

{"capacities":[1,1,2],"ships":[3]}

Output

0

Explanation: The sole ship can hold up to 3 containers and a total weight of 3. The three containers together weigh 1+1+2=4, which exceeds the ship's weight limit. Therefore no valid distribution exists and the result is 0.

Constraints

  • 1 <= capacities.length <= 15
  • 1 <= ships.length <= 10
  • 1 <= capacities[i] <= 20
  • 1 <= ships[j] <= 30

Optimal Approach & Strategy

Use recursion with memoization on (containerIndex, shipIdx, remainingWeight, remainingSlots) to count ways, yielding pseudo‑polynomial DP.

Brute Force Approach

Try every possible assignment of each container to any ship, checking constraints after each full assignment – exponential time.

Code Solutions

JavaScript Solution
Time: O(n*m*W*C)
function countDistributions(capacities, ships) {
    const n = capacities.length;
    const m = ships.length;
    if (n === 0) return 1;
    const remWeight = ships.slice(); // copy
    const remCnt = ships.slice(); // same limit for count
    function dfs(idx) {
        if (idx === n) return 1;
        let ways = 0;
        for (let i = 0; i < m; ++i) {
            if (capacities[idx] <= remWeight[i] && remCnt[i] > 0) {
                remWeight[i] -= capacities[idx];
                remCnt[i]--;
                ways += dfs(idx + 1);
                remWeight[i] += capacities[idx];
                remCnt[i]++;
            }
        }
        return ways;
    }
    return dfs(0);
}

// Example driver
const capacities = [1, 2];
const ships = [3, 2];
console.log(countDistributions(capacities, ships));

Asked in Top Tech Interviews

Salesforce

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.