Definition
Interval dynamic programming is an extension of linear dynamic programming. When the problem is divided into stages, it depends heavily on the order in which elements appear in a stage and on which elements from the preceding stage are merged to form it.
Let the state denote the maximum value obtained by merging all elements from positions through . Then , where is the value obtained by merging the two groups of elements.
Properties
Interval DP has the following characteristics:
Merging: combine two or more parts; the operation can of course also be viewed in reverse.
Structure: the problem can be decomposed into parts that can be merged pairwise.
Solution: define the optimum for the whole problem, enumerate the split point, divide the problem into left and right parts, and finally merge the two optimal values to obtain the optimum for the original problem.
Explanation
Examples
「NOI1995」Stone Merging
Problem statement: There are numbers arranged on a circle. Perform merge operations; each operation merges two adjacent piles into one and scores the sum of the stones in the newly formed pile. Maximize the total score.
First consider the case where the piles form a chain rather than a circle.
Let be the maximum score for merging all stones in the interval .
The state transition is .
Let denote the prefix sum of the array . The transition can then be written as .
Performing the State Transition
To compute , we need all values of and . Both intervals contain fewer elements than , so use as the DP stage. Enumerate in increasing order, then enumerate , calculate from and , and finally enumerate . The time complexity is .
Handling the Circle
How should we handle the fact that the stones form a circle rather than a chain?
Method 1: Enumerate the position at which to cut the circle and turn it into a chain. Since there are possible cuts, the final time complexity is .
Method 2: Extend the chain to twice its length, obtaining piles, where pile is identical to pile . Solve it with dynamic programming, then take the optimum among as the final answer. The time complexity is .
Implementation
C++
for (len = 2; len <= n; len++)
for (i = 1; i <= 2 * n - len; i++) {
int j = len + i - 1;
for (k = i; k < j; k++)
f[i][j] = max(f[i][j], f[i][k] + f[k + 1][j] + sum[j] - sum[i - 1]);
}
Python
for len in range(2, n + 1):
for i in range(1, 2 * n - len + 1):
j = len + i - 1
for k in range(i, j):
f[i][j] = max(f[i][j], f[i][k] + f[k + 1][j] + sum[j] - sum[i - 1])