You are given `n` balloons, indexed from `0` to `n - 1`. Each balloon is painted with a number on it, represented by an array `nums`. You are asked to burst all the balloons. If you burst the `i-th` balloon, you will get `nums[i - 1] * nums[i] * nums[i + 1]` coins. After the burst, the `i - 1` and `i + 1` then becomes adjacent. Find the maximum coins you can collect by bursting the balloons wisely.
Interval Dynamic Programming
Instead of thinking about which balloon to burst *first*, think about which balloon is burst *last* in a given range `[i, j]`. If the $k$-th balloon is burst last in `[i, j]`, the coins gained are `nums[i-1] * nums[k] * nums[j+1] + dp[i][k-1] + dp[k+1][j]`. We use a 2D DP table where `dp[i][j]` stores the maximum coins for the range from index `i` to `j`.