Related Articles
Minimize cost to reduce array to a single element by replacing K consecutive elements by their sum
• Last Updated : 12 Apr, 2021

Given an array arr[] of size N and an integer K, the task is to find the minimum cost required to reduce given array to a single element, where cost of replacing K consecutive array elements by their sum is equal to the sum of the K consecutive elements. If it is not possible to reduce given array to a single element, then print -1.

Examples:

Input: arr[] = {3, 5, 1, 2, 6}, K = 3
Output: 25
Explanation:
Replacing {arr, arr, arr} modifies arr[] = {3, 8, 6}. Cost = 8
Replacing {arr, arr, arr} modifies arr[] = {17}. Cost = 17.
Therefore, the total cost to merge all the array elements into  one = 8 + 17 = 25

Input: arr[] = {3, 2, 4, 1}, K = 3
Output: -1
Merging any K (=3) consecutive array elements left 2 elements in the array.
Therefore, the required output is -1.

Approach: The problem can be solved using Dynamic programming. Following is the recurrence relation:

Since the size of the array reduces by (K – 1) after every replacement operation,
dp[i][j] = min(dp[i][x], dp[x+1][j]), X = i + integer * (K – 1)
where, dp[i][j] stores the minimum cost to merge maximum number of array elements in the interval [i, j] with the left most element arr[i] always involved in merge if possible

Follow the steps below to solve the problem:

• If (N – 1) % (K – 1) != 0 then print -1.
• Initialize an array, say prefixSum[] to store the prefix sum of the given array.
• Initialize a 2D array, say dp[][], where dp[i][j] stores the minimum cost to merge the max number of array elements in the interval [i, j].
• Fill the DP table using the above-mentioned relationship between the DP states.
• Finally, print the value of dp[N – 1].

Below is the implementation of the above approach:

## C++

 `// C++ program to implement``// the above approach``#include``using` `namespace` `std;` `// Function to find the minimum cost``// to reduce given array to a single``// element by replacing consecutive``// K array elements``int` `minimumCostToMergeK(``int` `arr[], ``int` `K, ``int` `N)``{` `    ``// If (N - 1) is not``    ``// multiple of (K - 1)``    ``if` `((N - 1) % (K - 1) != 0)``    ``{``        ``return` `-1;``    ``}``    ` `    ``// Store prefix sum of the array``    ``int` `prefixSum[N + 1] = {0};` `    ``// Iterate over the range [1, N]``    ``for``(``int` `i = 1; i < (N + 1); i++)``    ``{``        ` `        ``// Update prefixSum[i]``        ``prefixSum[i] = (prefixSum[i - 1] + arr[i - 1]);` `    ``}` `    ``// dp[i][j]: Store minimum cost to``    ``// merge array elements interval [i, j]``    ``int` `dp[N][N];``    ``memset``(dp, 0, ``sizeof``(dp));` `    ``// L: Stores length of interval [i, j]``    ``for``(``int` `L = K; L < (N + 1); L++)``    ``{``        ` `        ``// Iterate over each interval``        ``// [i, j] of length L in in [0, N]``        ``for``(``int` `i = 0; i < (N - L + 1); i++)``        ``{``            ` `            ``// Stores index of last element``            ``// of the interval [i, j]``            ``int` `j = i + L - 1;` `            ``// If L is greater than K``            ``if` `(L > K)``            ``{``                ``int` `temp = INT_MAX;``                ``for``(``int` `x = i; x < j; x += K - 1)``                ``{``                    ``temp = min(temp, dp[i][x] +``                                     ``dp[x + 1][j]);``                ``}``                ` `                ``// Update dp[i][j]``                ``dp[i][j] = temp;``            ``}` `            ``// If (L - 1) is multiple of (K - 1)``            ``if` `((L - 1) % (K - 1) == 0)``            ``{``                ` `                ``// Update dp[i][j]``                ``dp[i][j] += (prefixSum[j + 1] -``                             ``prefixSum[i]);``            ``}``        ``}``    ``}``    ` `    ``// Return dp[N - 1]``    ``return` `dp[N - 1];``}` `// Driver Code``int` `main()``{``    ``int` `arr[] = { 3, 5, 1, 2, 6 };``    ``int` `K = 3;``    ` `      ``// Stores length of arr``      ``int` `N = ``sizeof``(arr) / ``sizeof``(arr);``      ` `    ``cout << minimumCostToMergeK(arr, K, N);``}` `// This code is contributed by rag2127`

## Java

 `// Java program to implement``// the above approach``import` `java.util.*;``class` `GFG``{` `  ``// Function to find the minimum cost``  ``// to reduce given array to a single``  ``// element by replacing consecutive``  ``// K array elements``  ``static` `int` `minimumCostToMergeK(``int` `arr[], ``int` `K, ``int` `N)``  ``{` `    ``// If (N - 1) is not``    ``// multiple of (K - 1)``    ``if` `((N - ``1``) % (K - ``1``) != ``0``)``    ``{``      ``return` `-``1``;``    ``}` `    ``// Store prefix sum of the array``    ``int` `[]prefixSum = ``new` `int``[N + ``1``];` `    ``// Iterate over the range [1, N]``    ``for``(``int` `i = ``1``; i < (N + ``1``); i++)``    ``{` `      ``// Update prefixSum[i]``      ``prefixSum[i] = (prefixSum[i - ``1``] + arr[i - ``1``]);` `    ``}` `    ``// dp[i][j]: Store minimum cost to``    ``// merge array elements interval [i, j]``    ``int` `[][]dp = ``new` `int``[N][N];` `    ``// L: Stores length of interval [i, j]``    ``for``(``int` `L = K; L < (N + ``1``); L++)``    ``{` `      ``// Iterate over each interval``      ``// [i, j] of length L in in [0, N]``      ``for``(``int` `i = ``0``; i < (N - L + ``1``); i++)``      ``{` `        ``// Stores index of last element``        ``// of the interval [i, j]``        ``int` `j = i + L - ``1``;` `        ``// If L is greater than K``        ``if` `(L > K)``        ``{``          ``int` `temp = Integer.MAX_VALUE;``          ``for``(``int` `x = i; x < j; x += K - ``1``)``          ``{``            ``temp = Math.min(temp, dp[i][x] +``                            ``dp[x + ``1``][j]);``          ``}` `          ``// Update dp[i][j]``          ``dp[i][j] = temp;``        ``}` `        ``// If (L - 1) is multiple of (K - 1)``        ``if` `((L - ``1``) % (K - ``1``) == ``0``)``        ``{` `          ``// Update dp[i][j]``          ``dp[i][j] += (prefixSum[j + ``1``] -``                       ``prefixSum[i]);``        ``}``      ``}``    ``}` `    ``// Return dp[N - 1]``    ``return` `dp[``0``][N - ``1``];``  ``}` `  ``// Driver Code``  ``public` `static` `void` `main(String[] args)``  ``{``    ``int` `arr[] = { ``3``, ``5``, ``1``, ``2``, ``6` `};``    ``int` `K = ``3``;` `    ``// Stores length of arr``    ``int` `N = arr.length;``    ``System.out.print(minimumCostToMergeK(arr, K, N));``  ``}``}` `// This code is contributed by shikhasingrajput`

## Python3

 `# Python3 program to implement``# the above approach` `# Function to find the minimum cost``# to reduce given array to a single``# element by replacing consecutive``# K array elements``def` `minimumCostToMergeK(arr, K): ``    ` `    ` `    ``# Stores length of arr``    ``N ``=` `len``(arr)` `    ``# If (N - 1) is not``    ``# multiple of (K - 1)``    ``if` `(N ``-` `1``) ``%` `(K ``-` `1``) !``=` `0``:``        ``return` `-``1``    ` `    ``# Store prefix sum of the array``    ``prefixSum ``=` `[``0``] ``*` `(N ``+` `1``)` `    ``# Iterate over the range [1, N]``    ``for` `i ``in` `range``(``1``, N ``+` `1``):` `        ``# Update prefixSum[i]``        ``prefixSum[i] ``=` `(prefixSum[i ``-` `1``]``                         ``+` `arr[i ``-` `1``])` `    ``# dp[i][j]: Store minimum cost to``    ``# merge array elements interval [i, j]``    ``dp ``=` `[[``0``]``*``N ``for` `_ ``in` `range``(N)]` `    ``# L: Stores length of interval [i, j]``    ``for` `L ``in` `range``(K, N ``+` `1``):` `        ``# Iterate over each interval``        ``# [i, j] of length L in in [0, N]``        ``for` `i ``in` `range``(N ``-` `L ``+` `1``):` `            ``# Stores index of last element``            ``# of the interval [i, j]``            ``j ``=` `i ``+` `L ``-` `1` `            ``# If L is greater than K``            ``if` `L > K:` `                ``# Update dp[i][j]``                ``dp[i][j] ``=``(``                     ``min``([dp[i][x] ``+` `dp[x ``+` `1``][j]``                     ``for` `x ``in` `range``(i, j, K``-``1``)]))``             ` `            ``# If (L - 1) is multiple of (K - 1)               ``            ``if` `(L ``-` `1``) ``%` `(K ``-` `1``) ``=``=` `0``:` `                ``# Update dp[i][j]``                ``dp[i][j] ``+``=` `(prefixSum[j ``+` `1``]``                              ``-` `prefixSum[i])` `    ``# Return dp[N - 1]``    ``return` `dp[``0``][N``-``1``]` `if` `__name__ ``=``=` `"__main__"``:``    ``arr ``=` `[``3``, ``5``, ``1``, ``2``, ``6``]``    ``K ``=` `3``    ``print``(minimumCostToMergeK(arr, K))`

## C#

 `// C# program to implement``// the above approach``using` `System;``class` `GFG``{` `  ``// Function to find the minimum cost``  ``// to reduce given array to a single``  ``// element by replacing consecutive``  ``// K array elements``  ``static` `int` `minimumCostToMergeK(``int` `[]arr, ``int` `K, ``int` `N)``  ``{` `    ``// If (N - 1) is not``    ``// multiple of (K - 1)``    ``if` `((N - 1) % (K - 1) != 0)``    ``{``      ``return` `-1;``    ``}` `    ``// Store prefix sum of the array``    ``int` `[]prefixSum = ``new` `int``[N + 1];` `    ``// Iterate over the range [1, N]``    ``for``(``int` `i = 1; i < (N + 1); i++)``    ``{` `      ``// Update prefixSum[i]``      ``prefixSum[i] = (prefixSum[i - 1] + arr[i - 1]);` `    ``}` `    ``// dp[i,j]: Store minimum cost to``    ``// merge array elements interval [i, j]``    ``int` `[,]dp = ``new` `int``[N,N];` `    ``// L: Stores length of interval [i, j]``    ``for``(``int` `L = K; L < (N + 1); L++)``    ``{` `      ``// Iterate over each interval``      ``// [i, j] of length L in in [0, N]``      ``for``(``int` `i = 0; i < (N - L + 1); i++)``      ``{` `        ``// Stores index of last element``        ``// of the interval [i, j]``        ``int` `j = i + L - 1;` `        ``// If L is greater than K``        ``if` `(L > K)``        ``{``          ``int` `temp = ``int``.MaxValue;``          ``for``(``int` `x = i; x < j; x += K - 1)``          ``{``            ``temp = Math.Min(temp, dp[i, x] +``                            ``dp[x + 1, j]);``          ``}` `          ``// Update dp[i,j]``          ``dp[i, j] = temp;``        ``}` `        ``// If (L - 1) is multiple of (K - 1)``        ``if` `((L - 1) % (K - 1) == 0)``        ``{` `          ``// Update dp[i,j]``          ``dp[i, j] += (prefixSum[j + 1] -``                       ``prefixSum[i]);``        ``}``      ``}``    ``}` `    ``// Return dp[0,N - 1]``    ``return` `dp[0, N - 1];``  ``}` `  ``// Driver Code``  ``public` `static` `void` `Main(String[] args)``  ``{``    ``int` `[]arr = { 3, 5, 1, 2, 6 };``    ``int` `K = 3;` `    ``// Stores length of arr``    ``int` `N = arr.Length;``    ``Console.Write(minimumCostToMergeK(arr, K, N));``  ``}``}` `// This code is contributed by 29AjayKumar`

## Javascript

 ``
Output:
`25`

Time Complexity: O(N2 * K)
Auxiliary Space: O(N2)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.   In case you are prepared, test your skills using TCS, Wipro, Amazon and Microsoft Test Serieses.

My Personal Notes arrow_drop_up