# Algorithms ## Dynamic Programming (Cormen, 3rd Ed.) 1. Characterize the structure of an optimal solution. 2. Recursively define the value of an optimal solution. - *optimal substructure*: optimal solutions to a problem incorporate optimal solutions to related subproblems, which we may solve independently - [數學歸納法 mathematical induction](https://youtu.be/hyvTl036PmA?t=86): 1. 起始步驟; *2. 歸納步驟* 3. Compute the value of an optimal solution: bottom-up or top-down with memo. 4. Construct an optimal solution from computed information. ### Rod-cutting 1. We can cut up a rod of length $n$ in $2^{n-1}$ different ways: if cut into $n$ pieces, there'd be $n-1$ cuts, for each cut either cut or no cut therefore $2^{n-1}$. 2. optimal revenue $r_n = max_{1⩽i⩽n}(p_i+r_{n-i})$, with $r_0 = 0$ ### Matrix-chain Multiplication - If $A_{i...k}$ and $A_{k+1...j}$ are both optimal, then $A_{i...k}\cdot A_{k+1...j}$ is optimal - $m_{i...j} = min_{i⩽k<j} (m_{i...k}+m_{k+1...j}+p_{i-1}{p_k}p_j)$ ## Complexity - [Is log a polynomial?](https://www.quora.com/Is-log-a-polynomial) no, but it's polynomial bound. ## Solutions ### LIS LeetCode [300](https://leetcode.com/problems/longest-increasing-subsequence/), [673](https://leetcode.com/problems/number-of-longest-increasing-subsequence/), [1713](https://leetcode.com/problems/minimum-operations-to-make-a-subsequence/) #### BF: O ($2^n$) #### [DP: O ($n^2$)](https://youtu.be/7DKFpWnaxLI?t=630) ```Python lis [k] = 0 for i in range (k): if a [k] > a [i]: lis [k] = max (lis [k], lis [i] + 1) ``` #### [DP + Greedy + Bin Srch: O ($n$log$n$)](https://youtu.be/l2rCz7skAlk?t=369) ```Python def idx (dp, p): # return where in dp the element is least but larger than p dp = [a [0]] for i in range (1, len (a)): j = idx (dp, i) if j < len (dp): dp [j] = a [i] else: dp.append (a [i]) ``` - binary (92ms) and sequental (comment, 248ms) search implementations of ```idx()``` ```Python def idx (dp, p): # for j in range (len (dp)): # if dp [j] >= p: # return j # return len (dp) lb = 0 ub = len (dp) - 1 while (lb <= ub): md = (lb + ub)//2 if dp [md] == p: return md elif dp [md] > p: ub = md - 1 else: lb = md + 1 return lb ``` ## 教學 - [Sort Scale](http://163.22.72.196/html5/html5_sort_scale/sort_scale.html)