Printing Sequences is a clean way to introduce interval dynamic programming. The goal is to determine whether a sequence can be generated with only a small number of PRINT commands, while repetition blocks can reuse previous output.
Define the DP state
The most important step is naming the subproblem:
dp[l][r] = minimum PRINT commands needed for sequence positions l through r - 1
This interval notation uses r as exclusive, which keeps split logic clean.
Two ways to build an interval
Every interval can be built by splitting it into two smaller intervals:
dp[l][r] = min(dp[l][m] + dp[m][r])
But the special trick is repetition. If an interval is made of repeated copies of a smaller block, the cost can be just the cost of one block.
1 2 1 2 = repeat [1 2] twice
cost = dp[0][2], not dp[0][4]
How to test repeated blocks
For a candidate block length, compare each element with the element one block earlier. If every block matches, the interval is repeated.
for i from l + blockLength to r - 1:
if a[i] != a[i - blockLength]:
not repeated
Common mistakes
- Forgetting the base case: a one-element interval costs one PRINT.
- Using inclusive endpoints inconsistently.
- Only checking split points and missing repeated-block compression.
- Recomputing interval answers instead of memoizing them.
Practice prompt
Compute the minimum PRINT count for [3, 4, 3, 4, 3, 4]. Then try [3, 4, 4, 3] and explain why the same repetition shortcut does or does not apply.
