Number of ways to divide an array into K equal sum sub-arrays

Given an integer K and an array arr[] of N integers, the task is to find the number of ways to split the array into K equal sum sub-arrays of non-zero lengths.
Examples:Â Â
Input: arr[] = {0, 0, 0, 0}, K = 3Â
Output: 3Â
All possible ways are:Â
{{0}, {0}, {0, 0}}Â
{{0}, {0, 0}, {0}}Â
{{0, 0}, {0}, {0}}
Input: arr[] = {1, -1, 1, -1}, K = 2Â
Output: 1Â Â
Approach: This problem can be solved using dynamic programming. Following will be our algorithm:Â
- Find the sum of all the elements of the array and store it in a variable SUM.Â
Before going to step 2, let’s try and understand the states of the DP.Â
For that, visualize putting bars to divide the array into K equal parts. So, we have to put K – 1 bar in total.Â
Thus, our states of dp will contain 2 terms.Â- i – index of the element we are currently upon.
- ck – number of bars we have already inserted + 1.
- Call a recursive function with i = 0 and ck = 1 and the recurrence relation will be:
Case 1: sum upto index i equals ((SUM)/k)* ckÂ
dp[i][ck] = dp[i+1][ck] + dp[i+1][ck+1]Â
Case 2: sum upto index not i equals ((SUM)/k)* ckÂ
dp[i][ck] = dp[i+1][ck]Â
Â
Below is the implementation of the above approach:Â Â
C++
// C++ implementation of the approach#include <bits/stdc++.h>#define max_size 20#define max_k 20using namespace std;Â
// Array to store the states of DPint dp[max_size][max_k];Â
// Array to check if a// state has been solved beforebool v[max_size][max_k];Â
// To store the sum of// the array elementsint sum = 0;Â
// Function to find the sum of// all the array elementsvoid findSum(int arr[], int n){Â Â Â Â for (int i = 0; i < n; i++)Â Â Â Â Â Â Â Â sum += arr[i];}Â
// Function to return the number of waysint cntWays(int arr[], int i, int ck,            int k, int n, int curr_sum){    // If sum is not divisible by k    // answer will be zero    if (sum % k != 0)        return 0;    if (i != n and ck == k + 1)        return 0;Â
    // Base case    if (i == n) {        if (ck == k + 1)            return 1;        else            return 0;    }Â
    // To check if a state    // has been solved before    if (v[i][ck])        return dp[i][ck];Â
    // Sum of all the numbers from the beginning    // of the array    curr_sum += arr[i];Â
    // Setting the current state as solved    v[i][ck] = 1;Â
    // Recurrence relation    dp[i][ck] = cntWays(arr, i + 1, ck, k, n, curr_sum);    if (curr_sum == (sum / k) * ck)        dp[i][ck] += cntWays(arr, i + 1, ck + 1, k, n, curr_sum);Â
    // Returning solved state    return dp[i][ck];}Â
// Driver codeint main(){Â Â Â Â int arr[] = { 1, -1, 1, -1, 1, -1 };Â Â Â Â int n = sizeof(arr) / sizeof(int);Â Â Â Â int k = 2;Â
    // Function call to find the    // sum of the array elements    findSum(arr, n);Â
    // Print the number of ways    cout << cntWays(arr, 0, 1, k, n, 0);} |
Java
// Java implementation of the approachclass GFG {Â Â Â Â Â static int max_size= 20;static int max_k =20;Â
// Array to store the states of DPstatic int [][]dp = new int[max_size][max_k];Â
// Array to check if a// state has been solved beforestatic boolean [][]v = new boolean[max_size][max_k];Â
// To store the sum of// the array elementsstatic int sum = 0;Â
// Function to find the sum of// all the array elementsstatic void findSum(int arr[], int n){Â Â Â Â for (int i = 0; i < n; i++)Â Â Â Â Â Â Â Â sum += arr[i];}Â
// Function to return the number of waysstatic int cntWays(int arr[], int i, int ck,            int k, int n, int curr_sum){    // If sum is not divisible by k    // answer will be zero    if (sum % k != 0)        return 0;    if (i != n && ck == k + 1)        return 0;Â
    // Base case    if (i == n)     {        if (ck == k + 1)            return 1;        else            return 0;    }Â
    // To check if a state    // has been solved before    if (v[i][ck])        return dp[i][ck];Â
    // Sum of all the numbers from the beginning    // of the array    curr_sum += arr[i];Â
    // Setting the current state as solved    v[i][ck] = true;Â
    // Recurrence relation    dp[i][ck] = cntWays(arr, i + 1, ck, k, n, curr_sum);    if (curr_sum == (sum / k) * ck)        dp[i][ck] += cntWays(arr, i + 1, ck + 1, k, n, curr_sum);Â
    // Returning solved state    return dp[i][ck];}Â
// Driver codepublic static void main(String[] args){Â Â Â Â int arr[] = { 1, -1, 1, -1, 1, -1 };Â Â Â Â int n = arr.length;Â Â Â Â int k = 2;Â
    // Function call to find the    // sum of the array elements    findSum(arr, n);Â
    // Print the number of ways    System.out.println(cntWays(arr, 0, 1, k, n, 0));}}Â
// This code is contributed by Princi Singh |
Python3
# Python3 implementation of the approachimport numpy as npÂ
max_size = 20max_k = 20Â
Â
# Array to store the states of DP dp = np.zeros((max_size,max_k)); Â
# Array to check if a # state has been solved before v = np.zeros((max_size,max_k)); Â
# To store the sum of # the array elements sum = 0; Â
# Function to find the sum of # all the array elements def findSum(arr, n) :     global sum    for i in range(n) :        sum += arr[i]; Â
Â
# Function to return the number of ways def cntWays(arr, i, ck, k, n, curr_sum) : Â
    # If sum is not divisible by k     # answer will be zero     if (sum % k != 0) :        return 0;     if (i != n and ck == k + 1) :        return 0; Â
    # Base case     if (i == n) :        if (ck == k + 1) :            return 1;         else :            return 0; Â
    # To check if a state     # has been solved before     if (v[i][ck]) :        return dp[i][ck]; Â
    # Sum of all the numbers from the beginning     # of the array     curr_sum += arr[i]; Â
    # Setting the current state as solved     v[i][ck] = 1; Â
    # Recurrence relation     dp[i][ck] = cntWays(arr, i + 1, ck, k, n, curr_sum);     if (curr_sum == (sum / k) * ck) :        dp[i][ck] += cntWays(arr, i + 1, ck + 1, k, n, curr_sum); Â
    # Returning solved state     return dp[i][ck];   Â
# Driver code if __name__ == "__main__" : Â
    arr = [ 1, -1, 1, -1, 1, -1 ];     n = len(arr);     k = 2; Â
    # Function call to find the     # sum of the array elements     findSum(arr, n); Â
    # Print the number of ways     print(cntWays(arr, 0, 1, k, n, 0)); Â
    # This code is contributed by AnkitRai01 |
C#
// C# implementation of the approachusing System;Â Â Â Â Â Â Â Â Â class GFG {Â Â Â Â Â static int max_size= 20;static int max_k =20;Â
// Array to store the states of DPstatic int [,]dp = new int[max_size, max_k];Â
// Array to check if a// state has been solved beforestatic Boolean [,]v = new Boolean[max_size, max_k];Â
// To store the sum of// the array elementsstatic int sum = 0;Â
// Function to find the sum of// all the array elementsstatic void findSum(int []arr, int n){Â Â Â Â for (int i = 0; i < n; i++)Â Â Â Â Â Â Â Â sum += arr[i];}Â
// Function to return the number of waysstatic int cntWays(int []arr, int i, int ck,            int k, int n, int curr_sum){    // If sum is not divisible by k    // answer will be zero    if (sum % k != 0)        return 0;    if (i != n && ck == k + 1)        return 0;Â
    // Base case    if (i == n)     {        if (ck == k + 1)            return 1;        else            return 0;    }Â
    // To check if a state    // has been solved before    if (v[i, ck])        return dp[i, ck];Â
    // Sum of all the numbers from the beginning    // of the array    curr_sum += arr[i];Â
    // Setting the current state as solved    v[i, ck] = true;Â
    // Recurrence relation    dp[i,ck] = cntWays(arr, i + 1, ck, k, n, curr_sum);    if (curr_sum == (sum / k) * ck)        dp[i, ck] += cntWays(arr, i + 1, ck + 1, k, n, curr_sum);Â
    // Returning solved state    return dp[i, ck];}Â
// Driver codepublic static void Main(String[] args){Â Â Â Â int []arr = { 1, -1, 1, -1, 1, -1 };Â Â Â Â int n = arr.Length;Â Â Â Â int k = 2;Â
    // Function call to find the    // sum of the array elements    findSum(arr, n);Â
    // Print the number of ways    Console.WriteLine(cntWays(arr, 0, 1, k, n, 0));}}Â
// This code contributed by Rajput-Ji |
Javascript
<script>Â
// Javascript implementation of the approachÂ
var max_size = 20;var max_k = 20Â
// Array to store the states of DPvar dp = Array.from(Array(max_size), ()=> Array(max_k));Â
// Array to check if a// state has been solved beforevar v = Array.from(Array(max_size), ()=> Array(max_k));Â
// To store the sum of// the array elementsvar sum = 0;Â
// Function to find the sum of// all the array elementsfunction findSum(arr, n){Â Â Â Â for (var i = 0; i < n; i++)Â Â Â Â Â Â Â Â sum += arr[i];}Â
// Function to return the number of waysfunction cntWays(arr, i, ck, k, n, curr_sum){    // If sum is not divisible by k    // answer will be zero    if (sum % k != 0)        return 0;    if (i != n && ck == k + 1)        return 0;Â
    // Base case    if (i == n) {        if (ck == k + 1)            return 1;        else            return 0;    }Â
    // To check if a state    // has been solved before    if (v[i][ck])        return dp[i][ck];Â
    // Sum of all the numbers from the beginning    // of the array    curr_sum += arr[i];Â
    // Setting the current state as solved    v[i][ck] = 1;Â
    // Recurrence relation    dp[i][ck] = cntWays(arr, i + 1, ck, k, n, curr_sum);    if (curr_sum == (sum / k) * ck)        dp[i][ck] += cntWays(arr, i + 1, ck + 1, k, n, curr_sum);Â
    // Returning solved state    return dp[i][ck];}Â
// Driver codevar arr = [1, -1, 1, -1, 1, -1];var n = arr.length;var k = 2;// Function call to find the// sum of the array elementsfindSum(arr, n);// Print the number of waysdocument.write( cntWays(arr, 0, 1, k, n, 0));Â
Â
</script> |
2
Â
Time Complexity: O(n*k)
Auxiliary Space: O(n*k)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



