ЁЯза рдзрдбрд╛ 11 тАФ Dynamic programming рдЖрдгрд┐ greedy: рдлрд│реНрдпрд╛рд╡рд░рдЪреА рдЙрддреНрддрд░реЗ
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 11 ┬╖ рдкреБрдвреЗ: lesson-12-choosing
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбреЗ 01тАУ11. exponential recursion рдЪреЗ linear table рдордзреНрдпреЗ рд░реВрдкрд╛рдВрддрд░, рдЪрд╛рд░ рдкрд╛рдпрд▒реНрдпрд╛рдВрдЪреА рдХреГрддреА, рдЖрдгрд┐ proof рд╕рд╛рдВрдЧреЗрд▓ рддреЗрд╡реНрд╣рд╛рдЪ рдЪрд╛рд▓рдгрд╛рд░рд╛ shortcut.
- dsa/algorithms.py тАФ
fib_memo,stairs,coin_change,max_meetings - dsa/demo.py тАФ
dp
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
рдореБрдЦреНрдпрд╛рдзреНрдпрд╛рдкрд┐рдХреЗрдиреЗ fib(25) 242,785 рд╡реЗрд│рд╛ рд╡рд┐рдЪрд╛рд░рд▓реЗ рд╣реЛрддреЗ, рдЖрдард╡рддреЗ? рдХреЙрд░рд┐рдбреЙрд░рдордзреНрдпреЗ рдПрдХ рдлрд│рд╛ рд▓рд╛рд╡рд╛: рдкрд╣рд┐рд▓реНрдпрд╛рдВрджрд╛ рдХреЛрдгреА "fib(17) = 1597" рдЕрд╕реЗ рдЙрддреНрддрд░ рджрд┐рд▓реЗ рдХреА рддреЗ рддрд┐рдереЗ рд▓рд┐рд╣рд╛. рдкреБрдврдЪреНрдпрд╛ рд╡реЗрд│реА рдЬреНрдпрд╛рд▓рд╛ рд╡рд┐рдЪрд╛рд░рд▓реЗ рдЬрд╛рдИрд▓ рддреЛ рддреНрдпрд╛рдРрд╡рдЬреА рдлрд│рд╛ рдкрд╛рд╣рддреЛ. рдЖрддрд╛ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рд╢реНрдирд╛рдЪреЗ рдЙрддреНрддрд░ рдПрдХрджрд╛рдЪ рдХрд╛рдврд▓реЗ рдЬрд╛рддреЗ: рдПрдХреВрдг 49. рд╣реЗ memoisation. рдХрд┐рдВрд╡рд╛ рдлрд│рд╛ рд╕реНрд╡рддрдГрдЪ рдЦрд╛рд▓реВрди рднрд░рд╛ тАФ fib(0), fib(1), fib(2)тАж тАФ рдХреЛрдгрд╛рд▓рд╛рд╣реА рди рд╡рд┐рдЪрд╛рд░рддрд╛: рд╣реЗ tabulation.
Greedy рд╡реЗрдЧрд│реЗ рдЖрд╣реЗ: рдлрд│рд╛ рдирд╛рд╣реА, рдкреНрд░рддреНрдпреЗрдХ рд╡реЗрд│реА рдлрдХреНрдд рд╕рд░реНрд╡рд╛рдд рдЪрд╛рдВрдЧрд▓реА рджрд┐рд╕рдгрд╛рд░реА рдкрд╛рдпрд░реА рдШреНрдпрд╛. рдПрдХрд╛ рдЦреЛрд▓реАрдд рдЬрд╛рд╕реНрддреАрдд рдЬрд╛рд╕реНрдд club meetings рдмрд╕рд╡рд╛рдпрд▓рд╛, рдиреЗрд╣рдореА рдЖрдзреА рд╕рдВрдкрдгрд╛рд░реА meeting рдШреНрдпрд╛. рд╣реЗ рдЪрд╛рд▓рддреЗ тАФ рддреНрдпрд╛рдЪрд╛ proof рдЖрд╣реЗ. 1, 3 рдЖрдгрд┐ 4 рдЪреНрдпрд╛ рдирд╛рдгреНрдпрд╛рдВрдиреА 6 рдмрдирд╡рддрд╛рдирд╛ "рдЖрдзреА рд╕рд░реНрд╡рд╛рдд рдореЛрдареЗ рдирд╛рдгреЗ" 4+1+1 = рддреАрди рдирд╛рдгреА рджреЗрддреЗ; рдлрд│рд╛ рд╕рд╛рдВрдЧрддреЛ 3+3 = рджреЛрди. рдХреЛрдгреАрддрд░реА рд╕рд┐рджреНрдз рдХреЗрд▓реЗ рдЕрд╕реЗрд▓ рддрд░рдЪ greedy рдмрд░реЛрдмрд░ рдЕрд╕рддреЛ.
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart LR
S0["stairs(0)=1"] --> S1["stairs(1)=1"] --> S2["stairs(2)=2"] --> S3["stairs(3)=3"] --> S4["stairs(4)=5"] --> Sn["тАж stairs(n) = stairs(nтИТ1) + stairs(nтИТ2)"]
тЭУ рдХрд╛рдп
- problem рдордзреНрдпреЗ overlapping sub-problems (рддреЛрдЪ рдЫреЛрдЯрд╛ рдкреНрд░рд╢реНрди рдкреБрдиреНрд╣рд╛ рдкреБрдиреНрд╣рд╛ рд╡рд┐рдЪрд╛рд░рд▓рд╛ рдЬрд╛рддреЛ) рдЖрдгрд┐ optimal substructure (рд╕рд░реНрд╡реЛрддреНрддрдо рдЙрддреНрддрд░ рдЫреЛрдЯреНрдпрд╛ рдкреНрд░рд╢реНрдирд╛рдВрдЪреНрдпрд╛ рд╕рд░реНрд╡реЛрддреНрддрдо рдЙрддреНрддрд░рд╛рдВрдкрд╛рд╕реВрди рдмрдирддреЗ) рдЕрд╕рддреАрд▓ рддреЗрд╡реНрд╣рд╛ DP рд▓рд╛рдЧреВ рд╣реЛрддреЗ.
- рдХреГрддреА: state (sub-problem рдХрд╕рд╛ рджрд┐рд╕рддреЛ?) тЖТ recurrence (рддреЛ рдЫреЛрдЯреНрдпрд╛ states рд╡рд░ рдХрд╕рд╛ рдЕрд╡рд▓рдВрдмреВрди рдЖрд╣реЗ?) тЖТ base cases тЖТ order (top-down memo рдХрд┐рдВрд╡рд╛ bottom-up table) тЖТ рдЙрддреНрддрд░.
stairs(n): ways = stairs(nтИТ1) + stairs(nтИТ2), O(n).coin_change: best[a] = 1 + min(best[aтИТc]), O(amount ├Ч coins). рдХреНрд▓рд╛рд╕рд┐рдХ рдЙрджрд╛рд╣рд░рдгреЗ: knapsack, edit distance, longest common subsequence, grid paths.- Greedy: рд╕реНрдерд╛рдирд┐рдХ рдкрд╛рддрд│реАрд╡рд░ рд╕рд░реНрд╡реЛрддреНрддрдо рдкрд░реНрдпрд╛рдп, рдХрдзреАрд╣реА рдкреБрдиреНрд╣рд╛ рди рддрдкрд╛рд╕рд▓реЗрд▓рд╛; O(n log n) рдХрд┐рдВрд╡рд╛ O(n); рдлрдХреНрдд exchange argument рдЕрд╕реЗрд▓ рддрд░рдЪ рдмрд░реЛрдмрд░ тАФ interval scheduling, Huffman, Dijkstra, canonical coin systems.
ЁЯдФ рдХрд╛
optimisation problems рдЪреНрдпрд╛ рдореЛрдареНрдпрд╛ рдХреБрдЯреБрдВрдмрд╛рд╕рд╛рдареА DP рдореНрд╣рдгрдЬреЗ "рд╕реЗрдХрдВрджрд╛рдВрдд рдЪрд╛рд▓рддреЗ" рдЖрдгрд┐ "рд╡рд┐рд╢реНрд╡рд╛рдЪрд╛ рдЕрдВрдд рд╣реЛрдИрдкрд░реНрдпрдВрддрд╣реА рд╕рдВрдкрдгрд╛рд░ рдирд╛рд╣реА" рдпрд╛рдВрддрд▓рд╛ рдлрд░рдХ; greedy рдореНрд╣рдгрдЬреЗ рд╣реБрд╢рд╛рд░ O(n log n) рдЖрдгрд┐ рдЪреБрдХреАрдЪреЗ рдЙрддреНрддрд░ рдпрд╛рдВрддрд▓рд╛ рдлрд░рдХ. рдХреЛрдгрддреЗ рдХреЛрдгрддреЗ рд╣реЗ рдУрд│рдЦрдгреЗ рд╣реЗрдЪ рдХреМрд╢рд▓реНрдп.
ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)
fib_memo recursion рд▓рд╛ dict рдЬреЛрдбрддреЛ; stairs рджреЛрди variables рдлрд┐рд░рд╡рдд рдареЗрд╡рддреЛ;
coin_change рд╕рд░реНрд╡реЛрддреНрддрдо counts рдЪреЗ table рднрд░рддреЛ рдЖрдгрд┐ рдЕрд╢рдХреНрдп рдЕрд╕реЗрд▓ рддрд░ тИТ1 рдкрд░рдд рдХрд░рддреЛ;
max_meetings end time рдиреБрд╕рд╛рд░ sort рдХрд░рддреЛ рдЖрдгрд┐ рдЬреЗ рдмрд╕рддреЗ рддреЗ рдШреЗрддреЛ.
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛
python3 dsa/demo.py dp
python3 - <<'EOF'
import sys; sys.path.insert(0, "dsa"); from algorithms import coin_change
def greedy(coins, amount):
n = 0
for c in sorted(coins, reverse=True): n += amount // c; amount %= c
return n if amount == 0 else -1
for coins, amt in (([1, 5, 10, 25], 63), ([1, 3, 4], 6), ([4, 7], 5)):
print(coins, amt, "greedy:", greedy(coins, amt), "DP:", coin_change(coins, amt))
# edit distance in four steps: state (i, j) ┬╖ recurrence min(replace, insert, delete) ┬╖ base i or j = 0 ┬╖ bottom-up
def edit(a, b):
T = [[0] * (len(b) + 1) for _ in range(len(a) + 1)]
for i in range(len(a) + 1):
for j in range(len(b) + 1):
T[i][j] = j if i == 0 else i if j == 0 else min(T[i-1][j-1] + (a[i-1] != b[j-1]), T[i-1][j] + 1, T[i][j-1] + 1)
return T[-1][-1]
print("edit('kitten', 'sitting') =", edit("kitten", "sitting"))
EOF
тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ
stairs(10) = 89, coin_change([1,5,10,25], 63) = 6, [4,7] рдиреЗ 5 рдмрдирд╡рдгреЗ
-1, meetings ['chess', 'coding', 'art']. US-рдкреНрд░рдХрд╛рд░рдЪреНрдпрд╛ рдирд╛рдгреНрдпрд╛рдВрд╕рд╛рдареА greedy DP рд╢реА
рд╕рд╣рдордд рд╣реЛрддреЛ, [1,3,4] рд╕рд╛рдареА DP 2 рджреЗрддреЗ рддрд┐рдереЗ greedy 3 рджреЗрддреЛ, рдЖрдгрд┐ edit distance
3 рдЖрд╣реЗ.
ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ
рдлрд│реНрдпрд╛рдЪреНрдпрд╛ рдорджрддреАрдиреЗ рддреБрдореНрд╣реА exponential recursion linear рдХреЗрд▓реЗ, table bottom-up рднрд░рд▓реЗ, рдЖрдгрд┐ рддреАрди рдирд╛рдгреНрдпрд╛рдВрдЪреНрдпрд╛ рдЙрджрд╛рд╣рд░рдгрд╛рдиреЗ greedy рд▓рд╛ рдЪреБрдХрддрд╛рдирд╛ рдкрдХрдбрд▓реЗ.
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
- mutable рдХрд┐рдВрд╡рд╛ unhashable state рд╡рд░ memoise рдХрд░рдгреЗ (tuples рд╡рд╛рдкрд░рд╛).
- tabulation рдордзреНрдпреЗ рдХреНрд░рдо рдЪреБрдХрдгреЗ (cell рднрд░рдгреНрдпрд╛рдЖрдзреАрдЪ рд╡рд╛рдЪрд▓реА рдЬрд╛рддреЗ).
- "рдЙрджрд╛рд╣рд░рдгрд╛рдВрд╡рд░ рдЪрд╛рд▓рд▓реЗ" рдореНрд╣рдгреВрди proof рд╢рд┐рд╡рд╛рдп greedy рд╡рд░ рд╡рд┐рд╢реНрд╡рд╛рд╕ рдареЗрд╡рдгреЗ.
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: diff tools (edit distance), spell checkers, resource allocation, text wrapping, рдЖрдгрд┐ рдкрд░реНрдпрд╛рдпрд╛рдВрд╡рд░рдЪрд╛ рдкреНрд░рддреНрдпреЗрдХ "рд╕рд░реНрд╡рд╛рдд рдХрдореА / рд╕рд░реНрд╡рд╛рдд рдЬрд╛рд╕реНрдд / рд╕рд░реНрд╡рд╛рдд рд╕реНрд╡рд╕реНрдд" рдкреНрд░рд╢реНрди тАФ DP рдХрд┐рдВрд╡рд╛ рд╕рд┐рджреНрдз рдХреЗрд▓реЗрд▓рд╛ greedy, рдЕрдВрджрд╛рдЬ рдХрдзреАрдЪ рдирд╛рд╣реА.
тПня╕П рдкреБрдвреЗ
рдзрдбрд╛ 12 тАФ рдпреЛрдЧреНрдп structure рдирд┐рд╡рдбрдгреЗ: рдкреНрд░рд╢реНрди рдард░рд╡рддреЛ, рдЖрдгрд┐ рдХрд│рд╕-рдкреНрд░рдХрд▓реНрдк (capstone).