Interval DP

Concept

Interval DP solves problems defined over contiguous subarrays (intervals). dp[i][j] represents the answer for the subarray from index i to j. Build solutions from smaller intervals to larger ones. At each step, consider choosing the left or right endpoint and combine with the solution of the remaining interval.

When to Use

  • Problems on contiguous subarrays where you pick from ends
  • Matrix chain multiplication
  • Optimal game strategy (two players picking from ends)
  • Merging stones, balloon bursting, palindrome problems

Intuition

Start with intervals of size 1 (base cases). Then solve size 2, size 3, and so on. For each interval [i, j], try all possible 'splits' or 'choices' and pick the optimal one. Think of a game where two players take turns picking from the left or right end of an array — interval DP models all possible game states. The key insight: the answer for [i, j] depends only on smaller intervals within it.

Complexity

Time
O(n^2) to O(n^3) depending on the problem
Space
O(n^2)

Template Code

cpp
#include<bits/stdc++.h>
using namespace std;

vector<vector<int>> dp(5005, vector<int>(5005, 0));

int main(){
    ios_base::sync_with_stdio(0), cin.tie(0);

    int n;
    cin >> n;

    vector<int> v(n);
    for(int i = 0; i < n; i++){
        cin >> v[i];
        dp[i+1][i+1] = v[i];
    }

    for(int size = 2; size <= n; size++){
        for(int i = 1; i <= n-size+1; i++){
            int j = i+size-1;

            int D = abs(v[i-1] - v[j-1]);

            int Left = v[i-1] + D + dp[i+1][j];
            int Right = v[j-1] + D + dp[i][j-1];

            dp[i][j] = max(Left, Right);
        }
    }

    cout << dp[1][n];
    return 0;
}

// Sample Input:
// 5
// 2 1 4 3 5
//
// Sample Output:
// 27