See all coding puzzles and patterns here.
Algorithm Description
Dynamic programming is a programming technique wherein a larger problem is broken down into a smaller subproblem plus a computation for the remainder of the problem.
DP algorithms generally construct a solution vector, which can be multidimensional, starting with a base case
and then building on that base case up toward the solution.
Once the target solution is constructed, it is returned.
The solution vector is generally called dp.
Example
For example, to solve the unbounded knapsack problem, we construct a solution vector dp of length
t equal to the target sum, where dp[i] indicates the number of ways that i can be
constructed using a sum of any of the available numbers.
We start with the base case dp[0] = 1 because 0 can be constructed in only one way, by using none of the elements.
Next we iterate over each element i in dp to compute the new j that can be
attained by adding each number in the available numbers to i.
If dp[i] is equal to 0, then we skip any additions because i cannot be attained,
implying that no sums can be constructed with i as the base.
For each number that can be attained, we add dp[i] to the existing value at dp[j].
The iteration over the dp is continued until the target sum t is computed in dp[t].
If we have a target of 10 and available numbers 2 and 4, and we want to know the number of ways 10 can be constructed as a sum of the available numbers, then the construction will look like:
setup: dp = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
i = 0: dp = [1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0]
i = 1: dp = [1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0]
i = 2: dp = [1, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0]
i = 3: dp = [1, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0]
i = 4: dp = [1, 0, 1, 0, 2, 0, 3, 0, 2, 0, 0]
i = 5: dp = [1, 0, 1, 0, 2, 0, 3, 0, 2, 0, 0]
i = 6: dp = [1, 0, 1, 0, 2, 0, 3, 0, 5, 0, 3]
i = 7: dp = [1, 0, 1, 0, 2, 0, 3, 0, 5, 0, 3]
i = 8: dp = [1, 0, 1, 0, 2, 0, 3, 0, 5, 0, 8]
i = 9: dp = [1, 0, 1, 0, 2, 0, 3, 0, 5, 0, 8]
The total permutations of 2 and 4 that can sum to 10 are:
2 + 2 + 2 + 2 + 2
2 + 2 + 2 + 4
2 + 4 + 4
2 + 2 + 4 + 2
2 + 4 + 2 + 2
4 + 2 + 2 + 2
4 + 2 + 4
4 + 4 + 2
If wanted to know the combinations adding to the target (i.e., only 2 + 2 + 2 + 2 + 2,
2 + 2 + 2 + 4 and 2 + 4 + 4) then we should store each combination as a set at each location
instead of just the number of permutations that add to that number.
In such a solution, we would initialize dp with every element set to an empty array, which would be
equivalent to a value of 0 in the permutations solution above, and then set dp[0] to an array
containing the empty set, which would be equivalent to the value 1 in the permutations solution above.
We would then add the newest element to the existing sets at each i and append the new set to the existing
array at the new sum.
The sequence would then be:
setup: dp = [[()], [], [], [], [], [], [], [], [], [], []]
i = 0: dp = [[()], [], [(2)], [], [(4)], [], [], [], [], [], []]
i = 1: dp = [[()], [], [(2)], [], [(4)], [], [], [], [], [], []]
i = 2: dp = [[()], [], [(2)], [], [(4), (2, 2)], [], [(4, 2)], [], [], [], []]
i = 3: dp = [[()], [], [(2)], [], [(4), (2, 2)], [], [(4, 2)], [], [], [], []]
i = 4: dp = [[()], [], [(2)], [], [(4), (2, 2)], [], [(4, 2), (2, 2, 2)], [], [(4, 4)], [], []]
i = 5: dp = [[()], [], [(2)], [], [(4), (2, 2)], [], [(4, 2), (2, 2, 2)], [], [(4, 4)], [], []]
i = 6: dp = [[()], [], [(2)], [], [(4), (2, 2)], [], [(4, 2), (2, 2, 2)], [], [(4, 4), (4, 2, 2), (2, 2, 2, 2)], [], []]
i = 7: dp = [[()], [], [(2)], [], [(4), (2, 2)], [], [(4, 2), (2, 2, 2)], [], [(4, 4), (4, 2, 2), (2, 2, 2, 2)], [], []]
i = 8: dp = [[()], [], [(2)], [], [(4), (2, 2)], [], [(4, 2), (2, 2, 2)], [], [(4, 4), (4, 2, 2), (2, 2, 2, 2)], [], [(4, 4, 2), (4, 2, 2, 2), (2, 2, 2, 2, 2)]]
i = 9: dp = [[()], [], [(2)], [], [(4), (2, 2)], [], [(4, 2), (2, 2, 2)], [], [(4, 4), (4, 2, 2), (2, 2, 2, 2)], [], [(4, 4, 2), (4, 2, 2, 2), (2, 2, 2, 2, 2)]]
Puzzles
| Puzzle | Difficulty | External Link |
| 0-1 Knapsack | Medium | |
| Biggest Square in City Skyline | Medium | |
| Distinct Subsequences | Medium | |
| Find Number of Palindromic Substrings in a String | Medium | |
| Longest Common Subsequence | Medium | Leetcode 1143 |
| Longest Common Substring | Medium | |
| Longest Increasing Subsequence | Medium | Leetcode 300 |
| Sums from Weighted Words | Medium |

