~/problems / 2-D dynamic programming / Interval (range) DP

Count ways to erase a string in adjacent pairs

hard ~45 min

You have a string of lowercase letters. One move deletes two adjacent equal letters; the pieces on either side then join up. You want to delete everything.

Write count_ways(s: str) -> int: the number of different move sequences that empty the string, modulo 10**9 + 7. Two sequences differ if at some step they delete a different pair.

Examples:

  • count_ways("aabb") == 2 (delete aa then bb, or bb then aa)
  • count_ways("abba") == 1 (bb must go first)
  • count_ways("aaaa") == 3 (first move: the left, middle or right pair; then one move left)
  • count_ways("abc") == 0

Constraints: 1 <= len(s) <= 500. The tests use up to 240 characters, so simulating moves is hopeless; aim for O(n³).

Show hint

in s[l..r], the first letter s[l] is eventually deleted together with some s[k] where s[k] == s[l]. Everything strictly between them must vanish first, and the part after k is independent. The two independent groups of moves can be interleaved in any order; count interleavings with a binomial coefficient.

Topic: Interval (range) DP. dp[l][r] over subarrays, filled by increasing length; pick the split point.

Read the visual guide
0:00
Ctrl ' run · Ctrl ↵ submit
esc