Dynamic Programming Change Making Get the least amount of coins to make a change. Consider an array of coins and an array stores the solution for each subproblem called solution Equation Complexity Consider the amount to make change for and total of coins provided, Time: Space: Example coins = [1, 2, 5] amount = 11 At first table starts with: amount + 1 for each cell H1 0 1 2 3 4 5 6 7 8 9 10 11 12 12 12 12 12 12 12 12 12 12 12 12 0 1 2 3 4 5 6 7 8 9 10 11 0 1 1 2 2 1 2 2 3 3 2 3 Code #include <iostream> using namespace std; int changeMaking(int coins[], int size, int amount){ int solution[amount + 1]; std::fill_n(solution, amount + 1, amount + 1); solution[0] = 0; for (int i = 1; i <= amount; i++) { for (int j = 0; j < size; j++) { if (coins[j] <= i) solution[i] = min(solution[i], solution[i - coins[j]] + 1); } } return solution[amount] > amount ? -1: solution[amount]; } int main() { int size = 3; int coins[size] = {1, 2, 5}; int amount = 11; cout << changeMaking(coins, size, amount); return 0; } Longest Common Subsequence Longest Common Subsequence (2 Strings) - Dynamic Programming & Competing Subproblems - YouTube Equation Consider an array A that stores the solution for each common subsequence of each subproblem. Thus, Three cases could occur: 1. if i = 0 or j = 0 which means two empty strings. 2. , if both characters from both strings are matched 3. , otherwise Complexity Consider two strings s1 and s2 with the respective lengths n and m Time: Space: Example Code public int LCS(String s1, String s2) { int cache[][] = new int[s2.length() + 1][s1.length() + 1]; for (int s2Row = 0; s2Row <= s2.length(); s2Row++) { for (int s1Col = 0; s1Col <= s1.length(); s1Col++) { if (s2Row == 0 || s1Col == 0) cache[s2Row][s1Col] = 0; else if (s2.charAt(s2Row - 1) == s1.charAt(s1Col - 1)) cache[s2Row][s1Col] = cache[s2Row - 1][s1Col - 1] + 1; else { cache[s2Row][s1Col] = Math.max( cache[s2Row - 1][s1Col], cache[s2Row][s1Col - 1] ); } } } return cache[s2.length()][s1.length()]; } Coin Collection A robot collecting coins in a grid of M x N . What's the maximum number of coins can be collected? The robot can only go forward to the right or down. Equation Consider an array board is the grid of coins and solution that stores the maximum number of coins collected at specific (i, j) . Complexity Filling the table takes: Tracing back: Example Code #include <iostream> using namespace std; int main() { const int rows = 6; const int columns = 6; int board[rows][columns] = { {0, 0, 1, 0, 0, 1}, {0, 0, 0, 1, 0, 0}, {0, 1, 0, 0, 1, 0}, {0, 0, 0, 1, 0, 0}, {1, 0, 0, 0, 1, 0}, {0, 0, 1, 0, 0, 1}, }; int solution[rows + 1][columns + 1]; for(int i = 0; i <= rows; i++) solution[i][0] = 0; for(int j = 0; j <= columns; j++) solution[0][j] = 0; for(int i = 1; i <= rows; i++) { for(int j = 1; j <= columns; j++){ solution[i][j] = max(solution[i - 1][j], solution[i][j - 1]) + board[i-1][j-1]; } } int i = rows, j = columns; stack<coordinate> coordinates; // trace back while(i > 0 && j > 0){ if(solution[i][j] == solution[i][j - 1] + board[i - 1][j - 1]){ coordinates.push({i, j - 1}); } else if(solution[i][j] == solution[i-1][j] + board[i - 1][j - 1]){ coordinates.push({i - 1, j}); } i--; j--; } for(int i = 0; i <= rows; i++) { for(int j = 0; j <= columns; j++) { cout << solution[i][j] << " "; } cout << endl; } return 0; } Dynamic Programming 0/1 Knapsack Consider a knapsack of capacity = 7 Value Weight #1 1 1 #2 4 3 #3 5 4 #4 7 5 0 1 2 3 4 5 6 7 1 0 1 1 1 1 1 1 1 3 0 1 1 4 5 5 5 5 4 0 1 1 4 5 6 6 9 5 0 1 1 4 5 7 8 9 Coin-row Example: 5, 1, 2, 10, 6, 3 index 0 coins V(n) 0 1 2 3 4 5 6 5 1 2 10 6 3 5 5 7 15 15 18 where is the number of coins. Equation Complexity Filling the table requires: Tracing back takes linear time. Code #include <iostream> #include <vector> using namespace std; vector<int> maximumAmountOfCoins(vector<int> coins, int size) { if(size < 2) return coins; int solution[size + 1]; solution[0] = 0; solution[1] = coins[0]; for(int i = 2; i <= size + 1; i++) solution[i] = max(coins[i - 1] + solution[i - 2], solution[i 1]); int maximumCoins = solution[size]; vector<int> chosen; for(int i = size; i >= 0; i--) { if(maximumCoins > solution[i - 1]) { maximumCoins -= coins[i - 1]; chosen.push_back(coins[i-1]); } } chosen.push_back(solution[size]); return chosen; } int main() { vector<int> coins = {5, 1, 2, 10, 6, 2}; vector<int> chosenCoins = maximumAmountOfCoins(coins, coins.size()); cout << "Chosen Coins: "; for(auto iterator = chosenCoins.begin(); iterator != chosenCoins.end(); ++iterator) { if(std::next(iterator) == chosenCoins.end()) { cout << "\nMaximum Coins: " << *iterator << endl; break; } cout << *iterator << " "; } return 0; } Binomial Coefficient