DP on Trees
Dynamic Programming: lesson 17 of 20
Every node returns two answers: taken, and not taken.
Lesson 17 of 20 · 7 min
DP on Trees
Step 1 of 9
No left-to-right order to sweep here. Each node will hand its parent two numbers: the best with it taken, and the best without.
The Idea
On a tree there is no left-to-right order to sweep, so the recursion carries the state instead. Each node returns two numbers: the best total if it is taken, and the best if it is skipped. A parent that takes itself may only add its children's skip values. The tree is walked once, bottom-up.
Real-World Example
An org chart planning a surprise party where nobody may be invited alongside their direct manager. Each team lead reports two totals upward — the best party including them and the best excluding them — and the CEO picks the larger of their own pair.
The Code
tree = {"a": ["b", "c"], "b": ["d", "e"], "c": [], "d": [], "e": []}
loot = {"a": 3, "b": 4, "c": 5, "d": 1, "e": 1}
def best(node):
take, skip = loot[node], 0
for kid in tree[node]:
kid_take, kid_skip = best(kid)
take += kid_skip # taking here forbids the children
skip += max(kid_take, kid_skip) # skipping here frees them
return take, skip
print(best("b")) # (4, 2)
print(max(best("a"))) # 9 — skip a, take b and cYour turn
What does this print?
tree = {"r": ["x"], "x": []}
loot = {"r": 2, "x": 5}
def best(node):
take, skip = loot[node], 0
for kid in tree[node]:
kid_take, kid_skip = best(kid)
take += kid_skip
skip += max(kid_take, kid_skip)
return take, skip
print(best("r"))Mini quiz
1 / 3