Dynamic Programming (DP)
Mind Map Summary
- Topic: Dynamic Programming (DP)
- Core Concepts:
- Optimal Substructure: A problem has optimal substructure if an optimal solution to the problem can be constructed from optimal solutions to its subproblems.
- Overlapping Subproblems: A problem has overlapping subproblems if the same subproblems are solved multiple times.
- Approaches:
- Memoization (Top-Down): A top-down approach where the results of expensive function calls are cached and returned when the same inputs occur again.
- Tabulation (Bottom-Up): A bottom-up approach where the results of the subproblems are stored in a table and used to solve larger subproblems.
Practice Exercise
Solve the Climbing Stairs problem. Find the maximum sum of a non-adjacent subarray. Solve the Coin Change problem. Find the Longest Common Subsequence of two strings.
Answer
1. Climbing Stairs:
public int ClimbStairs(int n) {
if (n == 1) return 1;
int[] dp = new int[n + 1];
dp[1] = 1;
dp[2] = 2;
for (int i = 3; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
2. Maximum Sum of a Non-Adjacent Subarray (House Robber):
public int Rob(int[] nums) {
if (nums.Length == 0) return 0;
if (nums.Length == 1) return nums[0];
int[] dp = new int[nums.Length];
dp[0] = nums[0];
dp[1] = Math.Max(nums[0], nums[1]);
for (int i = 2; i < nums.Length; i++) {
dp[i] = Math.Max(dp[i - 1], dp[i - 2] + nums[i]);
}
return dp[nums.Length - 1];
}
3. Coin Change:
public int CoinChange(int[] coins, int amount) {
int[] dp = new int[amount + 1];
Array.Fill(dp, amount + 1);
dp[0] = 0;
for (int i = 1; i <= amount; i++) {
for (int j = 0; j < coins.Length; j++) {
if (coins[j] <= i) {
dp[i] = Math.Min(dp[i], dp[i - coins[j]] + 1);
}
}
}
return dp[amount] > amount ? -1 : dp[amount];
}
4. Longest Common Subsequence:
public int LongestCommonSubsequence(string text1, string text2) {
int m = text1.Length;
int n = text2.Length;
int[,] dp = new int[m + 1, n + 1];
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (text1[i - 1] == text2[j - 1]) {
dp[i, j] = 1 + dp[i - 1, j - 1];
} else {
dp[i, j] = Math.Max(dp[i - 1, j], dp[i, j - 1]);
}
}
}
return dp[m, n];
}