Fill a small 0/1 knapsack table where each row decides whether one more item is available.

Algorithm

Steps

  1. Create a table with one extra row for using zero items.
  2. Process the four items in fixed order.
  3. For each capacity, inherit when the item is too heavy.
  4. Otherwise compare skip and take from the previous row.
  5. Print the best value and the full deterministic table.
state transition `dp[i][w]` compares skipping item `i` with taking it and reading the remaining capacity from the previous row.

Complexity

  • Time: O(item_count * capacity)
  • Space: O(item_count * capacity)

Visual walkthrough

The pinned items have weights [2, 3, 4, 5], values [3, 4, 5, 6], and capacity 5. The diagrams show each item row, the overweight inherit branch, and the skip-versus-take comparison that produces 7.

Step 1 - Zero items baseline

With no items available, every capacity has value 0.

Row 0: the empty knapsack is worth zero at every capacity.rowcap 0cap 1cap 2cap 3cap 4cap 50 items000000

Step 2 - First item fills a row

Item 1 has weight 2 and value 3, so capacities below 2 inherit 0 and capacities 2 through 5 can take it.

Row 1 after processing item 1 (weight 2, value 3).rowcap 0cap 1cap 2cap 3cap 4cap 5item 1003333choiceinheritinherittaketaketaketake

Step 3 - Overweight capacity inherits

For item 2 (weight 3, value 4) at capacity 2, weight 3 is too large, so the cell inherits skip = 3 from the previous row.

The overweight branch does not read a negative-capacity cell.decisionitemcapskiptakeresultinherit2 (w=3, v=4)23too heavy3row 2 cap 2w > cap2row 1—inherit

Step 4 - Skip or take at capacity 5

At capacity 5 for item 2, skip = 3 while take = 4 + dp[1][2] = 7, so max(skip, take) is 7.

Item 2 improves capacity 5 by taking the item and using the previous row at capacity 2.cellitemcurrent capskip: prev row cap 5take: prev row cap - weight 2resultcompare2 (w=3, v=4)534 + 3 = 77readprevious rowcap 5dp[1][5]dp[1][2] (5 - 3)max

Step 5 - Final processed row reaches value 7

After processing item 4, the final DP row is [0, 0, 3, 4, 5, 7]; item 4 is only the last processed row, not a reconstructed selected-item set.

Complete 0/1 knapsack table for weights [2, 3, 4, 5] and values [3, 4, 5, 6]; the final row means all four items have been processed.rowcap 0cap 1cap 2cap 3cap 4cap 50 items000000item 1003333item 2003447item 3003457item 4 (final processed row)003457

Java DSA Implementation

Basic.java
public class Basic {
  static String rowString(int[] row) {
    StringBuilder out = new StringBuilder("[");
    for (int i = 0; i < row.length; i++) {
      if (i > 0) out.append(", ");
      out.append(row[i]);
    }
    return out.append("]").toString();
  }
  static String tableString(int[][] table) {
    StringBuilder out = new StringBuilder("[");
    for (int i = 0; i < table.length; i++) {
      if (i > 0) out.append(", ");
      out.append(rowString(table[i]));
    }
    return out.append("]").toString();
  }
  public static void main(String[] args) {
    int[] weights = {2, 3, 4, 5};
    int[] values = {3, 4, 5, 6};
    int capacity = 5;
    int[][] dp = new int[weights.length + 1][capacity + 1];
    for (int item = 1; item <= weights.length; item++) {
      int weight = weights[item - 1];
      int value = values[item - 1];
      for (int cap = 0; cap <= capacity; cap++) {
        if (weight > cap) dp[item][cap] = dp[item - 1][cap];
        else {
          int skip = dp[item - 1][cap];
          int take = value + dp[item - 1][cap - weight];
          dp[item][cap] = Math.max(skip, take);
        }
      }
    }
    System.out.println(dp[weights.length][capacity]);
    System.out.println(tableString(dp));
  }
}

Output

7
[[0, 0, 0, 0, 0, 0], [0, 0, 3, 3, 3, 3], [0, 0, 3, 4, 4, 7], [0, 0, 3, 4, 5, 7], [0, 0, 3, 4, 5, 7]]

Implementation notes

  • Java stores weights and values in primitive int[] arrays and the DP table in an int[][] allocated as new int[weights.length + 1][capacity + 1]. The table starts with Java's default zero initialization, so row 0 already represents using no items.
  • The outer loop is item-first: item runs from 1 through weights.length, then binds weight = weights[item - 1] and value = values[item - 1]. The inner cap loop fills capacities 0 through capacity.
  • If weight > cap, the current cell copies dp[item - 1][cap]. Otherwise skip and take = value + dp[item - 1][cap - weight] are primitive int candidates, and Math.max(skip, take) writes the chosen value into the current row.
  • The small checked-in values keep integer sums far from overflow. The replay exposes whole row states, ending with row 4 as [0, 0, 3, 4, 5, 7] and answer 7.
  • In Java, int[][] is an array of row arrays, so allocation is the outer reference array plus one primitive row array per item count. The custom rowString and tableString helpers allocate StringBuilder objects, builder backing storage, and returned String objects for deterministic output, all managed by JVM GC.