# Minimize cost to reduce array to a single element by replacing K consecutive elements by their sum

• Difficulty Level : Hard
• 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[1], arr[2], arr[3]} modifies arr[] = {3, 8, 6}. Cost = 8
Replacing {arr[0], arr[1], arr[2]} 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[0][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[0][N - 1]` `    ``return` `dp[0][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[0]);` `      `  `    ``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[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;` `    ``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[0][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)

My Personal Notes arrow_drop_up
Related Articles