|
| 1 | +## Dynamic-programming |
| 2 | +### Use cases |
| 3 | +* When to use - optimize time complexity from O(n!,2^n) to O(n^2, n^3) |
| 4 | + - Calculate max or min |
| 5 | + - Calculate the number of solutions |
| 6 | + - Calculate whether it is true or not |
| 7 | +* When not to use - optimize time complexity from O(n^3, n^2) further |
| 8 | + - Calculate concrete solutions themselves rather than just the number of solutions |
| 9 | + - Input is a collection rather than a sequence (e.g. Longest consecutive sequence) |
| 10 | + |
| 11 | +### Problems to consider |
| 12 | +* State: how to define dp[i] or dp[i][j] |
| 13 | +* Induction rule: how to calculate big problems into smaller ones |
| 14 | +* Initialization: starting point |
| 15 | +* Answer: ending point |
| 16 | + |
| 17 | +### Implementation methods: |
| 18 | +* Multi-loop: bottom-up approach |
| 19 | +* Memorized search: top-down approach |
| 20 | +* Use cases: |
| 21 | + - In most cases, both of them can be applied. Could start with bottom-up approach because it is usually more concise. |
| 22 | + - But some times memorized search is more appropriate |
| 23 | + + When it is easier to start thinking from the last step rather than the first step. Example: Burst ballons, Stone-game (Leetcode) |
| 24 | + + When the induction rule is not sequential, thus hard to define. Example: Longest increasing subsequences in 2D (Leetcode) |
| 25 | + + When the initialization state is hard to find. Example: Longest increasing subsequences in 2D (Leetcode) |
| 26 | + |
| 27 | +### Memorization array tricks |
| 28 | +* For non grid-based dynamic programming problems, for N number/character, array of size N+1 is allocated. The position at 0 index is used for specially used for initialization. |
| 29 | +* Rolling array |
| 30 | + - for 1D dp, e.g. |
| 31 | + + If induction rule is f[i] = max(f[i-1], f[i-2]) + A[i], namely f[i] only depends on f[i-1] and f[i-2] |
| 32 | + + To use rolling array, induction rule can be rewritten as f[i%2] = max(f[i-1]%2, f[i-2]%2) |
| 33 | + - for 2D dp, e.g. |
| 34 | + + if f[i][j] only depends on f[i][.], namely i th row only depends on i-1 th row |
| 35 | + + To use rolling array, induction rule can be rewritten as f[i%2][j] = f[(i-1)%2] row |
| 36 | + - procedures to use rolling array: write non-rolling version first, then write rolling version |
| 37 | + |
| 38 | +```java |
| 39 | +// this code snippet demonstrate procedures to use rolling array |
| 40 | +// 1D case |
| 41 | +// first step: write a solution not based on rolling array |
| 42 | +public int houseRobber( int[] A ) |
| 43 | +{ |
| 44 | + int n = A.length; |
| 45 | + if ( n == 0 ) |
| 46 | + { |
| 47 | + return 0; |
| 48 | + } |
| 49 | + long[] res = new long[n+1]; |
| 50 | + |
| 51 | + res[0] = 0; |
| 52 | + res[1] = A[0]; |
| 53 | + for ( int i = 2; i <= n; i++ ) |
| 54 | + { |
| 55 | + res[i] = Math.max( res[i-1], res[i-2] + A[i-1]); |
| 56 | + } |
| 57 | + return res[n]; |
| 58 | +} |
| 59 | +// second step: use mod % to transform solution to rolling array |
| 60 | +// res[i] is only related with res[i-1] and res[i-2], mod 2 |
| 61 | +public int houseRobber_RollingArray( int[] A ) |
| 62 | +{ |
| 63 | + int n = A.length; |
| 64 | + if ( n == 0 ) |
| 65 | + { |
| 66 | + return 0; |
| 67 | + } |
| 68 | + long[] res = new long[2]; |
| 69 | + |
| 70 | + res[0] = 0; |
| 71 | + res[1] = A[0]; |
| 72 | + for ( int i = 2; i <= n; i++ ) |
| 73 | + { |
| 74 | + // key change here: %k, k is related with number of elements being relied on |
| 75 | + res[i%2] = Math.max( res[(i-1)%2], res[(i-2)%2] + A[i-1]); |
| 76 | + } |
| 77 | + return res[n]; |
| 78 | +} |
| 79 | +``` |
| 80 | + |
| 81 | +### Type |
| 82 | +- Coordinate based |
| 83 | + + Patterns: |
| 84 | + * state: f[x,y] represents goes to x,y position from starting point |
| 85 | + * induction rule: f[x,y] from f[x-1, y] or f[x, y-1] |
| 86 | + * initialization: f[0,0~width], f[0~height, 0] |
| 87 | + * answer: usually f[m,n] |
| 88 | + + Examples: Minimum Path Sum, Unique Path I�, Climbing stairs, Jump game I/II |
| 89 | +- 1D sequence |
| 90 | + + Patterns: |
| 91 | + * state: f[i] represents first i position, digits, characters |
| 92 | + * induction rule: f[i] from f[j], j < i |
| 93 | + * initialize: f[0] = 0, f[1] |
| 94 | + * answer: f[n] |
| 95 | + + Examples: Longest increasing subsequence, Word break I, House robber |
| 96 | +- 2D sequences |
| 97 | + + Patterns: |
| 98 | + * state: f[i,j] represents the results of first i numbers/characters in sequence one matching the first j numbers/characters in sequence two |
| 99 | + * induction rule: how to decide f[i,j] from previous (varies a lot here) |
| 100 | + * initialize: f[0,i] and f[i,0] |
| 101 | + * answer: f[n,m]( n = s1.length(), m = s2.length() ) |
| 102 | + + Examples: Edit distance, Regular expression matching, Longest common subsequences, Maximal rectangle/Square |
| 103 | +- Range based |
| 104 | + + Patterns: |
| 105 | + * state: f[i,j] represents whether the substring from i to j is a palindrome |
| 106 | + * induction rule: f[i,j] = f[i+1,j-1] && (s[i] == s[j]) |
| 107 | + * initialize: f[i][i] = true, f[i][i+1] = s[i] == s[i+1] |
| 108 | + * answer: f[0,n] |
| 109 | + + Examples: Palindrome partition II, Coins in a line III (Leetcode), Stone game, Burst ballons, Scramble string |
| 110 | +- Game |
| 111 | + + Patterns: |
| 112 | + * state: f[i] represents win/lose max/min profit for the first person |
| 113 | + * induction rule: avoid defining second person's state because second person always tries his best to defeat first person/make first person profit least. |
| 114 | + * initialize: varies with problem |
| 115 | + * answer: f[n] |
| 116 | + + Examples: Coin in a line (Leetcode), Coin in a line II (Leetcode), Flip game II |
| 117 | +- Backpack |
| 118 | + + Patterns: |
| 119 | + * state: f[i][S]: whether the first i items could form S/Max value/number of ways |
| 120 | + * induction rule: varies with problems |
| 121 | + * initialize: varies with problems |
| 122 | + * answer: varies with problems |
| 123 | + + Examples: Backpack I-VI (Leetcode), K Sum (Leetcode), Minimum adjustment cost (Leetcode) |
0 commit comments