# Clustering/Partitioning an array such that sum of square differences is minimum

• Difficulty Level : Hard
• Last Updated : 21 Apr, 2022

Given an array of n numbers and a number k. We need to divide the array into k partitions (clusters) of the same or different lengths. For a given k, there can be one or more ways to make clusters (partitions). We define a function Cost(i) for the ith cluster, as the square of the difference between its first and last element. If the current cluster is

, where leni is the length of current cluster, then :

Amongst all the possible kinds of partitions, we have to find the partition that will minimize the function,

Examples :

Input : arr[] = {1, 5, 8, 10}
k = 2
Output : 20
Explanation :
Consider clustering 4 elements 1, 5, 8, 10
into 2 clusters. There are three options:
1. S1 = 1, S2 = 5, 8, 10, with total cost
02 + 52 = 25.

2. S1 = 1, 5, S2 = 8, 10, with total cost
42 + 22 = 20

3. S1 = 1, 5, 8, S2 = 10, with total cost
72 + 02 = 49

So, the optimal clustering is the second one,

so the output of the above problem is 20.
Input : arr[] = {5, 8, 1, 10}
k = 3

Output :
9
Explanation :
The three partitions are {5, 8}, {1} and {10}

To solve the problem, we assume that we have k slabs. We have to insert them in some k different positions in the array, which will give us the required partition scheme, and the one having a minimum value for f(x) will be the answer.
Naive solution:
If we solve the above problem by the naive method, we would simply take all the possibilities and compute the minimum.

## C++

 // C++ program to find minimum cost k partitions// of array.#includeusing namespace std; // Initialize answer as infinite.const int inf = 1000000000;int ans = inf; // function to generate all possible answers.// and compute minimum of all costs.// i   --> is index of previous partition// par --> is current number of partitions// a[] and n --> Input array and its size// current_ans --> Cost of partitions made so far.void solve(int i, int par, int a[], int n,                  int k, int current_ans){    // If number of partitions is more than k    if (par > k)        return;     // If we have made k partitions and have    // reached last element    if (par==k && i==n-1)    {        ans = min(ans, current_ans);        return;    }     // 1) Partition array at different points    // 2) For every point, increase count of    //    partitions, "par" by 1.    // 3) Before recursive call, add cost of    //    the partition to current_ans    for (int j=i+1; j

## Java

 // Java program to find minimum cost k partitions// of array.import java.io.*; class GFG{    // Initialize answer as infinite.    static int inf = 1000000000;    static int ans = inf;         // function to generate all possible answers.    // and compute minimum of all costs.    // i --> is index of previous partition    // par --> is current number of partitions    // a[] and n --> Input array and its size    // current_ans --> Cost of partitions made so far.    static void solve(int i, int par, int a[], int n,                               int k, int current_ans)    {        // If number of partitions is more than k        if (par > k)            return;             // If we have made k partitions and have        // reached last element        if (par == k && i == n - 1)        {            ans = Math.min(ans, current_ans);            return;        }             // 1) Partition array at different points        // 2) For every point, increase count of        // partitions, "par" by 1.        // 3) Before recursive call, add cost of        // the partition to current_ans        for (int j = i + 1; j < n; j++)            solve(j, par + 1, a, n, k, current_ans +                 (a[j] - a[i + 1]) * (a[j] - a[i + 1]));    }         // Driver code    public static void main (String[] args)    {        int k = 2;        int a[] = {1, 5, 8, 10};        int n = a.length;        solve(-1, 0, a, n, k, 0);        System.out.println(ans);             }} // This code is contributed by vt_m.

## Python3

 # Python3 program to find minimum# cost k partitions of array. # Initialize answer as infinite.inf = 1000000000ans = inf # function to generate all possible answers.# and compute minimum of all costs.# i --> is index of previous partition# par --> is current number of partitions# a[] and n --> Input array and its size# current_ans --> Cost of partitions made so far.def solve(i, par, a, n, k, current_ans):         # If number of partitions is more than k    if (par > k):        return 0             # If we have made k partitions and    # have reached last element    global ans    if (par == k and i == n - 1):        ans = min(ans, current_ans)        return 0     # 1) Partition array at different points    # 2) For every point, increase count of    # partitions, "par" by 1.    # 3) Before recursive call, add cost of    # the partition to current_ans    for j in range(i + 1, n):        solve(j, par + 1, a, n, k, current_ans +             (a[j] - a[i + 1]) * (a[j] - a[i + 1])) # Driver codek = 2a = [1, 5, 8, 10]n = len(a)solve(-1, 0, a, n, k, 0)print(ans) # This code is contributed by sahilshelangia

## C#

 // C# program to find minimum// cost k partitions of array.using System; class GFG{    // Initialize answer as infinite.    static int inf = 1000000000;    static int ans = inf;         // function to generate all possible answers.    // and compute minimum of all costs.    // i --> is index of previous partition    // par --> is current number of partitions    // a[] and n --> Input array and its size    // current_ans --> Cost of partitions made so far.    static void solve(int i, int par, int []a,                      int n, int k, int current_ans)    {        // If number of partitions is more than k        if (par > k)            return;             // If we have made k partitions and        // have reached last element        if (par == k && i == n - 1)        {            ans = Math.Min(ans, current_ans);            return;        }             // 1) Partition array at different points        // 2) For every point, increase count of        // partitions, "par" by 1.        // 3) Before recursive call, add cost of        // the partition to current_ans        for (int j = i + 1; j < n; j++)            solve(j, par + 1, a, n, k, current_ans +                 (a[j] - a[i + 1]) * (a[j] - a[i + 1]));    }         // Driver code    public static void Main ()    {        int k = 2;        int []a = {1, 5, 8, 10};        int n = a.Length;        solve(-1, 0, a, n, k, 0);        Console.Write(ans);    }} // This code is contributed by nitin mittal.

## PHP

  is index of previous partition// par --> is current number of partitions// a[] and n --> Input array and its size// current_ans --> Cost of partitions made so far.function solve($i, $par, &$a, $n, $k, $current_ans){    global $inf, $ans;         // If number of partitions is    // more than k    if ($par > $k)        return;     // If we have made k partitions and    // have reached last element    if ($par == $k && $i == $n - 1)    {        $ans = min($ans, $current_ans); return; }  // 1) Partition array at different points // 2) For every point, increase count of // partitions, "par" by 1. // 3) Before recursive call, add cost of // the partition to current_ans for ($j = $i + 1; $j < $n; $j++)        solve($j, $par + 1, $a, $n, $k, $current_ans +                           ($a[$j] - $a[$i + 1]) *                           ($a[$j] - $a[$i + 1]));} // Driver code$k = 2;$a = array(1, 5, 8, 10);$n = sizeof($a);solve(-1, 0, $a, $n, $k, 0);echo $ans . "\n"; // This code is contributed by ita_c?>

## Javascript

 

Output:

20

Time Complexity: It’s clear that the above algorithm has Time Complexity of  O(2n)

Dynamic Programming:
We create a table dp[n+1][k+1] table and initialize all values as infinite.

dp[i][j] stores optimal partition cost
for arr[0..i-1] and j partitions.

Let us compute the value of dp[i][j]. we take an index m, such that m < i, and put a partition next to that position such that there is no slab in between the indices i and m. It can be seen simply that answer to the current scenario is dp[m][j-1] + (a[i-1]-a[m])*(a[i-1]-a[m]), where the first term signifies the minimum f(x) till the mth element with j-1 partitions and the second one signifies the cost of current cluster. So we will take the minimum of all the possible indices m and dp[i][j] will be assigned the minimum amongst them.

## C++

 // C++ program to find minimum cost k partitions// of array.#includeusing namespace std;const int inf = 1000000000; // Returns minimum cost of partitioning a[] in// k clusters.int minCost(int a[], int n, int k){    // Create a dp[][] table and initialize    // all values as infinite. dp[i][j] is    // going to store optimal partition cost    // for arr[0..i-1] and j partitions    int dp[n+1][k+1];    for (int i=0; i<=n; i++)        for (int j=0;j<=k;j++)            dp[i][j] = inf;     // Fill dp[][] in bottom up manner    dp[0][0] = 0;     // Current ending position (After i-th    // iteration result for a[0..i-1] is computed.    for (int i=1;i<=n;i++)         // j is number of partitions        for (int j=1;j<=k;j++)             // Picking previous partition for            // current i.            for (int m=i-1;m>=0;m--)                dp[i][j] = min(dp[i][j], dp[m][j-1] +                          (a[i-1]-a[m])*(a[i-1]-a[m]));      return dp[n][k];} // Driver codeint main(){    int k = 2;    int a[] = {1, 5, 8, 10};    int n = sizeof(a)/sizeof(a[0]);    cout << minCost(a, n, k) << endl;    return 0;}

## Java

 // Java program to find minimum cost// k partitions of array.import java.io.*; class GFG{    static int inf = 1000000000;         // Returns minimum cost of partitioning    // a[] in k clusters.    static int minCost(int a[], int n, int k)    {        // Create a dp[][] table and initialize        // all values as infinite. dp[i][j] is        // going to store optimal partition cost        // for arr[0..i-1] and j partitions        int dp[][] = new int[n + 1][k + 1];        for (int i = 0; i <= n; i++)            for (int j = 0; j <= k; j++)                dp[i][j] = inf;             // Fill dp[][] in bottom up manner        dp[0][0] = 0;             // Current ending position (After i-th        // iteration result for a[0..i-1] is computed.        for (int i = 1; i <= n; i++)                 // j is number of partitions            for (int j = 1; j <= k; j++)                     // Picking previous partition for                // current i.                for (int m = i - 1; m >= 0; m--)                    dp[i][j] = Math.min(dp[i][j], dp[m][j - 1] +                              (a[i - 1] - a[m]) * (a[i - 1] - a[m]));                  return dp[n][k];    }         // Driver code    public static void main (String[] args)    {        int k = 2;        int a[] = {1, 5, 8, 10};        int n = a.length;        System.out.println(minCost(a, n, k));                 }} // This code is contributed by vt_m.

## Python3

 # Python3 program to find minimum cost k partitions# of array.inf = 1000000000; # Returns minimum cost of partitioning a[] in# k clusters.def minCost(a, n, k):     # Create a dp[][] table and initialize    # all values as infinite. dp[i][j] is    # going to store optimal partition cost    # for arr[0..i-1] and j partitions    dp = [[inf for i in range(k + 1)]               for j in range(n + 1)];     # Fill dp[][] in bottom up manner    dp[0][0] = 0;     # Current ending position (After i-th    # iteration result for a[0..i-1] is computed.    for i in range(1, n + 1):         # j is number of partitions        for j in range(1, k + 1):             # Picking previous partition for            # current i.            for m in range(i - 1, -1, -1):                dp[i][j] = min(dp[i][j], dp[m][j - 1] +                                    (a[i - 1] - a[m]) *                                    (a[i - 1] - a[m]));     return dp[n][k]; # Driver codeif __name__ == '__main__':    k = 2;    a = [1, 5, 8, 10];    n = len(a);    print(minCost(a, n, k)); # This code is contributed by 29AjayKumar

## C#

 // C# program to find minimum cost// k partitions of array.using System; class GFG {         static int inf = 1000000000;         // Returns minimum cost of partitioning    // a[] in k clusters.    static int minCost(int []a, int n, int k)    {                 // Create a dp[][] table and initialize        // all values as infinite. dp[i][j] is        // going to store optimal partition cost        // for arr[0..i-1] and j partitions        int [,]dp = new int[n + 1,k + 1];        for (int i = 0; i <= n; i++)            for (int j = 0; j <= k; j++)                dp[i,j] = inf;             // Fill dp[][] in bottom        // up manner        dp[0,0] = 0;             // Current ending position        // (After i-th iteration        // result for a[0..i-1]        // is computed.        for (int i = 1; i <= n; i++)                 // j is number of partitions            for (int j = 1; j <= k; j++)                     // Picking previous                // partition for                // current i.                for (int m = i - 1; m >= 0; m--)                    dp[i,j] = Math.Min(dp[i,j],                                 dp[m,j - 1] +                               (a[i - 1] - a[m]) *                               (a[i - 1] - a[m]));                  return dp[n,k];    }         // Driver code    public static void Main ()    {        int k = 2;        int []a = {1, 5, 8, 10};        int n = a.Length;        Console.Write(minCost(a, n, k));                 }} // This code is contributed by nitin mittal

## Javascript

 

Output:

20`

Time Complexity: Having the three simple loops, the complexity of the above algorithm is  O(n2k)

This article is contributed by Amritya Vagmi and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

My Personal Notes arrow_drop_up