Recurrence

for (Group g : groups)
  for (int w = W; w >= 0; w--)
    for (Item item : g.items)
      if (item.weight <= w)
        dp[w] = Math.max(dp[w], dp[w - item.weight] + item.value);
Advertisement

Why inner loop order matters

Update dp[w] considering each item in group but only using dp[w-weight] from previous group (avoid picking 2 from same group).

Advertisement

Applications

Course selection: pick 1 from each requirement group. Team formation with position constraints.

Complexity

O(W × sum of group sizes) = O(W × N).