Paths through a grid
A robot starts top-left and can only move right or down. How many routes reach each cell? Every cell is reached from above or from the left, so ways[r][c] = ways[r-1][c] + ways[r][c-1]:
public class Main {
public static void main(String[] args) {
int rows = 4, cols = 5;
long[][] ways = new long[rows][cols];
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
if (r == 0 || c == 0) ways[r][c] = 1; // edges: only one way
else ways[r][c] = ways[r - 1][c] + ways[r][c - 1];
}
}
for (long[] row : ways) System.out.println(java.util.Arrays.toString(row));
}
}Output
[1, 1, 1, 1, 1] [1, 2, 3, 4, 5] [1, 3, 6, 10, 15] [1, 4, 10, 20, 35]
The 0/1 knapsack
A bag holds at most W kg. Each item has a weight and a value, and you take it or leave it. Maximise the value. dp[i][w] = the best value using the first i items with capacity w:
public class Main {
public static void main(String[] args) {
int[] weight = {1, 3, 4, 5};
int[] value = {15, 50, 60, 90};
int W = 8, n = weight.length;
int[][] dp = new int[n + 1][W + 1];
for (int i = 1; i <= n; i++) {
for (int w = 0; w <= W; w++) {
dp[i][w] = dp[i - 1][w]; // leave item i
if (weight[i - 1] <= w) { // or take it
dp[i][w] = Math.max(dp[i][w], value[i - 1] + dp[i - 1][w - weight[i - 1]]);
}
}
}
System.out.println("best value: " + dp[n][W]);
}
}Output
best value: 140
Longest common subsequence
A subsequence keeps letters in order but may skip some: “ace” is a subsequence of “abcde”. The longest subsequence two words share measures how similar they are (used by diff tools and DNA research). dp[i][j] = the LCS length of the first i letters of a and the first j of b:
public class Main {
static int lcs(String a, String b) {
int[][] dp = new int[a.length() + 1][b.length() + 1];
for (int i = 1; i <= a.length(); i++) {
for (int j = 1; j <= b.length(); j++) {
if (a.charAt(i - 1) == b.charAt(j - 1)) dp[i][j] = dp[i - 1][j - 1] + 1; // letters match
else dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); // drop one letter
}
}
return dp[a.length()][b.length()];
}
public static void main(String[] args) {
System.out.println(lcs("abcde", "ace"));
System.out.println(lcs("JAVASCRIPT", "JAVA"));
System.out.println(lcs("dog", "cat"));
}
}Output
3 4 0
Common mistake: Mixing up indexes. With an extra row and column of zeros,
dp[i][j]is about lettersi - 1andj - 1. That extra row/column is what makes the base cases free.