๐ฏ Interval DP & Partition DP: The Art of Breaking Problems Into Pieces
Imagine you have a long chocolate bar. You want to break it into tiny squares, but each break costs energy. How do you break it smartly to use the least energy?
๐ซ The Chocolate Bar Story
Letโs say you have a chocolate bar with 5 squares in a row. You want to break it into individual pieces. Every time you break, it costs 1 coin multiplied by the length of the piece youโre breaking.
Hereโs the magic question: In what ORDER should you break to spend the fewest coins?
This is Interval DP โ finding the best way to handle a range of things by trying every possible way to split it!
๐ช What is Interval DP?
Simple Idea: You have a row of items (like beads on a string). You want to do something with the WHOLE row. But you can only work with smaller pieces first.
๐งฉ The Core Pattern
Think of it like this:
[-------whole problem-------]
โ try splitting here
[--left--] + [--right--]
You try EVERY possible split point. For each split:
- Solve the left piece
- Solve the right piece
- Combine them
- Pick the best combination!
๐ฆ Real-Life Analogy: Merging Stone Piles
Imagine you have 4 piles of stones in a row:
Pile 1 Pile 2 Pile 3 Pile 4
3 7 2 5
Rule: You can only merge adjacent piles (neighbors). The cost to merge = sum of stones in both piles.
Goal: Merge all piles into ONE pile with minimum cost.
๐ค Why Order Matters
Bad order:
- Merge pile 1+2 โ Cost: 3+7 = 10 โ New pile: 10
- Merge 10+3 โ Cost: 10+2 = 12 โ New pile: 12
- Merge 12+4 โ Cost: 12+5 = 17 โ New pile: 17
- Total: 10 + 12 + 17 = 39
Better order:
- Merge pile 3+4 โ Cost: 2+5 = 7 โ New pile: 7
- Merge pile 1+2 โ Cost: 3+7 = 10 โ New pile: 10
- Merge 10+7 โ Cost: 17 โ Final pile: 17
- Total: 7 + 10 + 17 = 34 โจ
Same piles, different order, different cost!
๐ง The Interval DP Recipe
# dp[i][j] = best answer for
# the range from i to j
for length in range(2, n+1):
for i in range(n - length + 1):
j = i + length - 1
# Try every split point k
for k in range(i, j):
left = dp[i][k]
right = dp[k+1][j]
combine_cost = cost(i, j, k)
dp[i][j] = best(
dp[i][j],
left + right + combine_cost
)
๐ Key Insight
We build answers for small ranges first, then use them to solve bigger ranges!
Length 1: [0], [1], [2], [3]
Length 2: [0,1], [1,2], [2,3]
Length 3: [0,1,2], [1,2,3]
Length 4: [0,1,2,3] โ Final answer!
๐ญ Classic Example: Matrix Chain Multiplication
You have matrices: A(10ร20), B(20ร30), C(30ร40)
Cost to multiply two matrices: rows ร common ร cols
Question: What order minimizes operations?
Option 1: (A ร B) ร C
- A ร B costs: 10 ร 20 ร 30 = 6,000
- Result ร C costs: 10 ร 30 ร 40 = 12,000
- Total: 18,000
Option 2: A ร (B ร C)
- B ร C costs: 20 ร 30 ร 40 = 24,000
- A ร Result costs: 10 ร 20 ร 40 = 8,000
- Total: 32,000
Option 1 wins! Same answer, but 14,000 fewer operations!
๐จ Partition DP: The Special Case
Partition DP is when you split something into exactly K parts.
๐ Pizza Cutting Analogy
You have a pizza with toppings worth different points. You want to cut it into exactly 3 slices to maximize the value.
Each slice has a โscoreโ based on toppings. But adjacent toppings might create bonus points!
๐ Partition DP Pattern
# dp[i][k] = best way to partition
# first i elements into k parts
for i in range(1, n+1):
for k in range(1, K+1):
for j in range(k-1, i):
# Last partition: j+1 to i
dp[i][k] = best(
dp[i][k],
dp[j][k-1] + value(j+1, i)
)
๐ฏ Classic Partition DP: Painterโs Problem
Story: You have a fence with sections that need painting. You have K painters. Each painter paints a continuous section.
The time to finish = the slowest painter.
Goal: Assign sections so the slowest painter finishes fastest!
Example
Fence sections take: [10, 20, 30, 40]
With 2 painters:
- Option A: [10, 20] and [30, 40] โ Times: 30 and 70 โ Max: 70
- Option B: [10, 20, 30] and [40] โ Times: 60 and 40 โ Max: 60
- Option C: [10] and [20, 30, 40] โ Times: 10 and 90 โ Max: 90
Option B wins! Slowest painter takes 60 units.
๐งฎ The Partition DP Code
def painter_partition(sections, K):
n = len(sections)
# prefix[i] = sum of first i sections
prefix = [0] * (n + 1)
for i in range(n):
prefix[i+1] = prefix[i] + sections[i]
# dp[i][k] = min time for
# first i sections with k painters
dp = [[float('inf')] * (K+1)
for _ in range(n+1)]
dp[0][0] = 0
for i in range(1, n+1):
for k in range(1, min(i, K)+1):
for j in range(k-1, i):
# Painter k does j+1 to i
time = prefix[i] - prefix[j]
worst = max(dp[j][k-1], time)
dp[i][k] = min(dp[i][k], worst)
return dp[n][K]
๐ When to Use Interval DP vs Partition DP
graph TD A["Problem has a<br>range/sequence?"] -->|Yes| B{Fixed number<br>of parts?} B -->|No| C["Interval DP<br>Try all splits"] B -->|Yes, K parts| D["Partition DP<br>Track part count"] C --> E["Stone Merging<br>Matrix Chain<br>Balloon Burst"] D --> F["Painter Problem<br>Book Allocation<br>Array Splitting"]
๐ช Interval DP: Balloon Burst
You have balloons with numbers. When you burst balloon i, you get:
coins = nums[left] ร nums[i] ร nums[right]
Goal: Burst all balloons to maximize coins!
The Trick: Think Backwards!
Instead of โwhich to burst first,โ think โwhich to burst LAST in this range?โ
If balloon k is the LAST one burst in range [i,j]:
- Left side
[i, k-1]is already burst - Right side
[k+1, j]is already burst - When we burst
k: neighbors arei-1andj+1!
def maxCoins(nums):
nums = [1] + nums + [1]
n = len(nums)
dp = [[0] * n for _ in range(n)]
for length in range(1, n-1):
for i in range(1, n - length):
j = i + length - 1
for k in range(i, j+1):
coins = nums[i-1]*nums[k]*nums[j+1]
dp[i][j] = max(
dp[i][j],
dp[i][k-1] + coins + dp[k+1][j]
)
return dp[1][n-2]
๐ Key Takeaways
Interval DP Checklist โ
- Problem involves a range or sequence
- You need to find best way to split/merge
- Build from small ranges to big ranges
- Try every possible split point
Partition DP Checklist โ
- Must divide into exactly K parts
- Each part is contiguous (no gaps)
- Track both position AND part count
- Often involves min-max or sum problems
๐ Practice Problems
- Stone Merging โ Merge stones with minimum cost
- Matrix Chain โ Multiply matrices optimally
- Balloon Burst โ Pop balloons for maximum coins
- Painterโs Partition โ Divide work among K workers
- Palindrome Partitioning โ Split into fewest palindromes
๐ฏ The Golden Rule
โFor Interval DP, think: What happens if I split HERE?โ โFor Partition DP, think: Where does the Kth group START?โ
Youโre not just solving a problem โ youโre exploring every possible universe of splits and picking the best one! ๐
