- CountingPathsByDP
- FibonacciByDP
- NChooseKByDP
- SubsetSumByDP
- MinWtTriangulationByDP
- KnapsackByDP
- TransitiveClosureByDP
- ShortestPathsByDP
- GoodrichAndTomassia sections 5.3.3 (0/1 knapsack), 6.4.2 (transitive closure), 7.1, 7.2.1

problem | subproblem | for each | recurrence | base case | final answer | run time |

count # s-> t paths | P[v] = #paths from s to v | vertex in graph | P[v] = ∑_{w: (u,w)∈ E} P[w] | P[s] = 1 | P[t] | O(#vertices+#edges) |

n choose k | C[i,j] = #size-j subsets of {1,2,...,i} | i=0,1,..,n; j=0,1,...,i | C[n,k] = C[n-1,k] + C[n-1,k-1] | C[n,0] = 1 C[0,i] = 0 (i > 0) | C[n,k] | O(n*k) |

∃ subset of S[1..n] summing to g? | ES[i,h] = true if subset of {1,2,..,i} sums to h | i=0,1,..,n; h=0,1,...,g | ES[i,h] = ES[i-1,h] or ES[i-1,h-S[i]] | ES[0,0] = true | ES[n,g] | O(n*g) |

min wt triangulation of {1,2,...,n} | MWT[i,j] = min wt triangulation of {i,i+1,..,j} | 1 ≤ i < j ≤ n | MWT[i,j] = min {cost[i,j] + MWT[i,k] + MWT[k,j] : k=i+1,i+2,...,j-1 } | MWT[i,i+1] = cost[i,i+1] | MWT[1,n] | O(n^{3}) |

longest ascending subsequence of {S[1],S[2],...,S[n]} | LAS[i] = longest ascending subsequence of {S[1],..S[i]} ending at S[i] | i=1,2,...,n | LAS[i] = max{ 1, max{ 1 + LAS[j] : j=1,2,..,i-1 and S[j] < S[i] } | - | max {LAS[i] : i=1,2,...,n} | O(n^{2}) |

See also ShortestPathsByDP ...

1. ask what subproblems you would need to solve in order to solve given problem

2. make sure the number of distinct subproblems is not too large

3. formulate a recurrence between subproblems

4. use the recurrence to design a recursive algorithm that caches, or an iterative algorithm