Related Articles
Minimum cost to merge all elements of List
• Difficulty Level : Hard
• Last Updated : 13 May, 2021

Given a list of N integers, the task is to merge all the elements of the list into one with the minimum possible cost. The rule for merging is as follows:
Choose any two adjacent elements of the list with values say X and Y and merge them into a single element with value (X + Y) paying a total cost of (X + Y).
Examples:

Input: arr[] = {1, 3, 7}
Output: 15
All possible ways of merging:
a) {1, 3, 7} (cost = 0) -> {4, 7} (cost = 0+4 = 4) -> 11 (cost = 4+11 = 15)
b) {1, 3, 7} (cost = 0) -> {1, 10} (cost = 0+10= 10) -> 11 (cost = 10+11 = 21)
Thus, ans = 15
Input: arr[] = {1, 2, 3, 4}
Output: 19

Approach: This problem can be solved using dynamic programming. Let’s define the states of the DP first. DP[l][r] will be the minimum cost of merging the subarray arr[l…r] into one.
Now, let’s look at the recurrence relation:

DP[l][r] = min(S(l, l) + S(l + 1, r) + DP[l][l] + DP[l + 1][r], S(l, l + 1) + S(l + 2, r) + DP[l][l + 1] + DP[l + 2][r], …, S(l, r – 1) + S(r, r) + DP[l][r – 1] + DP[r][r]) = S(l, r) + min(DP[l][l] + DP[l + 1][r], DP[l][l + 1] + DP[l + 2][r], …, DP[l][r – 1] + DP[r][r])
where S(x, y) is the sum of all the elements of the subarray arr[x…y]

The time complexity of the approach will be O(N3) as there are N * N states in total and each state takes O(N) time to solve in general.
Below is the implementation of the above approach:

## CPP

 // C++ implementation of the approach#include using namespace std; #define N 401 // To store the states of DPint dp[N][N];bool v[N][N]; // Function to return the minimum merge costint minMergeCost(int i, int j, int* arr){     // Base case    if (i == j)        return 0;     // If the state has been solved before    if (v[i][j])        return dp[i][j];     // Marking the state as solved    v[i][j] = 1;    int& x = dp[i][j];     // Reference to dp[i][j]    x = INT_MAX;     // To store the sum of all the    // elements in the subarray arr[i...j]    int tot = 0;    for (int k = i; k <= j; k++)        tot += arr[k];     // Loop to iterate the recurrence    for (int k = i + 1; k <= j; k++) {        x = min(x, tot + minMergeCost(i, k - 1, arr)                       + minMergeCost(k, j, arr));    }     // Returning the solved value    return x;} // Driver codeint main(){    int arr[] = { 1, 3, 7 };    int n = sizeof(arr) / sizeof(int);     cout << minMergeCost(0, n - 1, arr);     return 0;}

## Java

 // Java implementation of the approachclass GFG{ static final int N = 401; // To store the states of DPstatic int [][]dp = new int[N][N];static boolean [][]v = new boolean[N][N]; // Function to return the minimum merge coststatic int minMergeCost(int i, int j, int[] arr){     // Base case    if (i == j)        return 0;     // If the state has been solved before    if (v[i][j])        return dp[i][j];     // Marking the state as solved    v[i][j] = true;    int x = dp[i][j];     // Reference to dp[i][j]    x = Integer.MAX_VALUE;     // To store the sum of all the    // elements in the subarray arr[i...j]    int tot = 0;    for (int k = i; k <= j; k++)        tot += arr[k];     // Loop to iterate the recurrence    for (int k = i + 1; k <= j; k++)    {        x = Math.min(x, tot + minMergeCost(i, k - 1, arr)                    + minMergeCost(k, j, arr));    }     // Returning the solved value    return x;} // Driver codepublic static void main(String[] args){    int arr[] = { 1, 3, 7 };    int n = arr.length;     System.out.print(minMergeCost(0, n - 1, arr));}} // This code is contributed by PrinciRaj1992

## Python3

 # Python3 implementation of the approachimport sys N = 401; # To store the states of DPdp = [[0 for i in range(N)] for j in range(N)];v = [[False for i in range(N)] for j in range(N)]; # Function to return the minimum merge costdef minMergeCost(i, j, arr):     # Base case    if (i == j):        return 0;     # If the state has been solved before    if (v[i][j]):        return dp[i][j];     # Marking the state as solved    v[i][j] = True;    x = dp[i][j];     # Reference to dp[i][j]    x = sys.maxsize;     # To store the sum of all the    # elements in the subarray arr[i...j]    tot = 0;    for k in range(i, j + 1):        tot += arr[k];     # Loop to iterate the recurrence    for k in range(i + 1, j + 1):        x = min(x, tot + minMergeCost(i, k - 1, arr) + \                minMergeCost(k, j, arr));         # Returning the solved value    return x; # Driver codeif __name__ == '__main__':    arr = [ 1, 3, 7 ];    n = len(arr);     print(minMergeCost(0, n - 1, arr)); # This code is contributed by PrinciRaj1992

## C#

 // C# implementation of the approachusing System; class GFG{ static readonly int N = 401; // To store the states of DPstatic int [,]dp = new int[N, N];static bool [,]v = new bool[N, N]; // Function to return the minimum merge coststatic int minMergeCost(int i, int j, int[] arr){     // Base case    if (i == j)        return 0;     // If the state has been solved before    if (v[i, j])        return dp[i, j];     // Marking the state as solved    v[i, j] = true;    int x = dp[i, j];     // Reference to dp[i,j]    x = int.MaxValue;     // To store the sum of all the    // elements in the subarray arr[i...j]    int tot = 0;    for (int k = i; k <= j; k++)        tot += arr[k];     // Loop to iterate the recurrence    for (int k = i + 1; k <= j; k++)    {        x = Math.Min(x, tot + minMergeCost(i, k - 1, arr)                    + minMergeCost(k, j, arr));    }     // Returning the solved value    return x;} // Driver codepublic static void Main(String[] args){    int []arr = { 1, 3, 7 };    int n = arr.Length;     Console.Write(minMergeCost(0, n - 1, arr));}} // This code is contributed by 29AjayKumar

## Javascript


Output:
15

My Personal Notes arrow_drop_up