Skip to content
Related Articles

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[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<bits/stdc++.h>
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




<script>
// javascript 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
    function minimumCostToMergeK(arr , K , N)
    {
 
        // If (N - 1) is not
        // multiple of (K - 1)
        if ((N - 1) % (K - 1) != 0) {
            return -1;
        }
 
        // Store prefix sum of the array
        var prefixSum = Array(N + 1).fill(0);
 
        // Iterate over the range [1, N]
        for (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]
        var dp = Array(N);
        for( i = 0; i<N;i++)
        dp[i] = Array(N).fill(0);
 
        // L: Stores length of interval [i, j]
        for (L = K; L < (N + 1); L++) {
 
            // Iterate over each interval
            // [i, j] of length L in in [0, N]
            for (i = 0; i < (N - L + 1); i++) {
 
                // Stores index of last element
                // of the interval [i, j]
                var j = i + L - 1;
 
                // If L is greater than K
                if (L > K) {
                    var temp = Number.MAX_VALUE;
                    for (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
     
        var arr = [ 3, 5, 1, 2, 6 ];
        var K = 3;
 
        // Stores length of arr
        var N = arr.length;
        document.write(minimumCostToMergeK(arr, K, N));
 
// This code is contributed by todaysgaurav
</script>
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
Recommended Articles
Page :