• There are nodes that have a value (a, b) where a and b are breakpoints. This">

    Program to Find Out the Minimum Parsing Tree in C++



    Suppose we have a list of unique and sorted numbers that represent breakpoints in a string. We want to create a tree out of these rules −

    • There are nodes that have a value (a, b) where a and b are breakpoints. This means the node spans from indices [a, b] in the string.

    • The root node spans over every breakpoint. (the whole string).

    • The spans of a node's left and right child are ordered, contiguous, and contains the parent node's span.

    • Leaf nodes' index of 'a' in breakpoints is 1 before the index of 'b' in breakpoints.

    The cost of a tree is determined as the sum of b - a for every node in the tree. Our goal is to determine the lowest possible cost of a feasible tree.

    So, if the input is like breakpoints = [1, 4, 7, 12], then the output will be 28.

    To solve this, we will follow these steps −

    • n := size of the input array breakpoints

    • if n <= 1, then −

      • return 0

    • if n is same as 2, then −

      • return breakpoints[1] - breakpoints[0]

    • Define an array p[n - 1]

    • for initialize i := 0, when i < n - 1, update (increase i by 1), do −

      • p[i] := breakpoints[i + 1]

    • Define an array pre[n]

    • for initialize i := 1, when i < n, update (increase i by 1), do −

      • pre[i] := pre[i - 1] + p[i - 1]

    • Define one 2D array dp[n, n] and initialize columns with infinity.

    • Define one 2D array op[n, n]

    • for initialize i := 1, when i < n, update (increase i by 1), do −

      • dp[i,i] := p[i - 1], op[i,i] := i

    • for initialize len := 2, when len < n, update (increase len by 1), do −

      • for initialize i := 1, when i + len - 1 < n, update (increase i by 1), do −

        • j := i + len - 1

        • idx := i

        • for initialize k := maximum of(i, op[i,j-1]), when k < minimum of (j - 1, op[i + 1, j]), update (increase k by 1), do −

          • cost := dp[i, k] + dp[k + 1, j]

          • if cost < dp[i, j], then −

            • idx := k

            • dp[i, j] := cost

        • op[i, j] := idx

        • dp[i, j] := dp[i, j] + pre[j] - pre[i - 1]

    • return dp[1, n - 1]

    Example 

    Let us see the following implementation to get better understanding −

     Live Demo

    #include <bits/stdc++.h>
    using namespace std;
    int solve(vector<int>& breakpoints) {
       int n = breakpoints.size();
       if (n <= 1) return 0;
       if (n == 2) return breakpoints[1] - breakpoints[0];
          vector<int> p(n - 1);
       for (int i = 0; i < n - 1; ++i) p[i] = breakpoints[i + 1] - breakpoints[i];
          vector<int> pre(n);
       for (int i = 1; i < n; ++i) pre[i] = pre[i - 1] + p[i - 1];
          vector<vector<int>> dp(n, vector<int>(n, INT_MAX));
          vector<vector<int>> op(n, vector<int>(n));
       for (int i = 1; i < n; ++i) dp[i][i] = p[i - 1], op[i][i] = i;
       for (int len = 2; len < n; ++len) {
          for (int i = 1; i + len - 1 < n; ++i) {
             int j = i + len - 1;
             int idx = i;
             for (int k = max(i, op[i][j - 1]); k <= min(j - 1, op[i + 1][j]); ++k) {
                int cost = dp[i][k] + dp[k + 1][j];
                if (cost < dp[i][j]) {
                   idx = k;
                   dp[i][j] = cost;
                }
             }
             op[i][j] = idx;
             dp[i][j] += pre[j] - pre[i - 1];
          }
       }
       return dp[1][n - 1];
    }
    int main(){
       vector<int> breakpoints = {1, 4, 7, 12};
       cout << solve(breakpoints) << endl;
       return 0;
    }

    Input

    {1, 4, 7, 12}

    Output

    28
    Kickstart Your Career

    Get certified by completing the course

    Get Started
    Advertisements