Skip to content

Commit 02d87ed

Browse files
committed
Adding DP
1 parent 18682c8 commit 02d87ed

File tree

1 file changed

+123
-0
lines changed

1 file changed

+123
-0
lines changed

algorithms/Dynamic-Programming.md

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
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

Comments
 (0)