 Open in App
Not now

# Count ways to split an array into subarrays such that sum of the i-th subarray is divisible by i

• Difficulty Level : Expert
• Last Updated : 31 Aug, 2021

Given an array arr[] consisting of N integers, the task is to find the number of ways to split the array into non-empty subarrays such that the sum of the ith subarray is divisible by i.

Examples:

Input: arr[] = {1, 2, 3, 4}
Output: 3
Explanation:
Following are the number of ways to split the array into non-empty subarray as:

1. Split the array into subarray as {1}, {2}, {3}, {4} and the sum of each of the ith subarray is divisible by i.
2. Split the array into subarray as {1, 2, 3}, {4} and each of the ith subarray is divisible by i.
3. Split the array into subarray as {1, 2, 3, 4} and each of the ith subarray is divisible by i.

As there are only 3 possible ways to split the given array. Therefore, print 3.

Input: arr[ ] = {1, 1, 1, 1, 1}
Output: 3

Approach: The given problem can be solved by using Dynamic Programming because it has overlapping subproblems and optimal substructure. The subproblems can be stored in dp[][] table using memoization where dp[i][j] stores the number of partitions till ith index of arr[] into j non-empty subarray. This idea can be implemented using the Prefix Sum array pre[] that store the sum of all elements till every ith index and dp[i][j] can be calculated as the sum of dp[k][j – 1] for all value of k < i such that (pre[i] – pre[k]) is a multiple of j. Follow the steps below to solve the given problem:

• Initialize a variable, say count that stores the number of possible splitting of the given array into subarray.
• Find the prefix sum of the array and store it in another array, say prefix[].
• Initialize a 2D array, say dp[][] that stores all the overlapping states dp[i][j].
• Iterate over the range [0, N] using the variable i and nested iterate over the range [N, 0] using the variable j and perform the following steps:
1. Increment the value of dp[j + 1][pre[i + 1] % (j + 1)] by the value of dp[j][pre[i + 1] % j] as this denotes the count of partitions till index i into j continuous subsequence divisible by (j + 1).
2. If the value of i is (N – 1), then update the value of count by dp[j][pre[i + 1] % j].
• After completing the above steps, print the value of count as the result.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;` `// Function to count ways to split``// an array into subarrays such that``// sum of the i-th subarray is``// divisible by i``int` `countOfWays(``int` `arr[], ``int` `N)``{` `    ``// Stores the prefix sum of array``    ``int` `pre[N + 1] = { 0 };``    ``for` `(``int` `i = 0; i < N; i++) {` `        ``// Find the prefix sum``        ``pre[i + 1] = pre[i] + arr[i];``    ``}` `    ``// Initialize dp[][] array``    ``int` `dp[N + 1][N + 1];``    ``memset``(dp, 0, ``sizeof``(dp));``    ``dp++;` `    ``// Stores the count of splitting``    ``int` `ans = 0;` `    ``// Iterate over the range [0, N]``    ``for` `(``int` `i = 0; i < N; i++) {``        ``for` `(``int` `j = N; j >= 1; j--) {` `            ``// Update the dp table``            ``dp[j + 1][pre[i + 1] % (j + 1)]``                ``+= dp[j][pre[i + 1] % j];` `            ``// If the last index is``            ``// reached, then add it``            ``// to the variable ans``            ``if` `(i == N - 1) {``                ``ans += dp[j][pre[i + 1] % j];``            ``}``        ``}``    ``}` `    ``// Return the possible count of``    ``// splitting of array into subarrays``    ``return` `ans;``}` `// Driver Code``int` `main()``{``    ``int` `arr[] = { 1, 2, 3, 4 };``    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr);` `    ``cout << countOfWays(arr, N);` `    ``return` `0;``}`

## Java

 `// Java program for the above approach` `public` `class` `GFG {``    `  `// Function to count ways to split``// an array into subarrays such that``// sum of the i-th subarray is``// divisible by i``static` `int` `countOfWays(``int` `arr[], ``int` `N)``{` `    ``// Stores the prefix sum of array``    ``int` `pre[] = ``new` `int``[N + ``1``];``    ` `    ``for` `(``int` `i = ``0``; i < N; i++) {` `        ``// Find the prefix sum``        ``pre[i + ``1``] = pre[i] + arr[i];``    ``}` `    ``// Initialize dp[][] array``    ``int` `dp[][] = ``new` `int` `[N + ``2``][N + ``2``];` `    ``dp[``1``][``0``]++;` `    ``// Stores the count of splitting``    ``int` `ans = ``0``;` `    ``// Iterate over the range [0, N]``    ``for` `(``int` `i = ``0``; i < N; i++) {``        ``for` `(``int` `j = N; j >= ``1``; j--) {` `            ``// Update the dp table``            ``dp[j + ``1``][pre[i + ``1``] % (j + ``1``)]``                ``+= dp[j][pre[i + ``1``] % j];` `            ``// If the last index is``            ``// reached, then add it``            ``// to the variable ans``            ``if` `(i == N - ``1``) {``                ``ans += dp[j][pre[i + ``1``] % j];``            ``}``        ``}``    ``}` `    ``// Return the possible count of``    ``// splitting of array into subarrays``    ``return` `ans;``}` `    ``// Driver Code``    ``public` `static` `void` `main (String[] args) {``        ` `            ``int` `arr[] = { ``1``, ``2``, ``3``, ``4` `};``            ``int` `N = arr.length;``        ` `            ``System.out.println(countOfWays(arr, N));``    ``}``}` `// This code is contributed by AnkThon`

## Python3

 `# Python3 program for the above approach` `import` `numpy as np` `# Function to count ways to split``# an array into subarrays such that``# sum of the i-th subarray is``# divisible by i``def` `countOfWays(arr, N) :` `    ``# Stores the prefix sum of array``    ``pre ``=` `[ ``0` `] ``*` `(N ``+` `1``);``    ` `    ``for` `i ``in` `range``(N) :` `        ``# Find the prefix sum``        ``pre[i ``+` `1``] ``=` `pre[i] ``+` `arr[i];` `    ``# Initialize dp[][] array``    ``dp ``=` `np.zeros((N ``+` `2``,N ``+` `2``));``    ``dp[``1``][``0``] ``+``=` `1``;` `    ``# Stores the count of splitting``    ``ans ``=` `0``;` `    ``# Iterate over the range [0, N]``    ``for` `i ``in` `range``(N) :``        ``for` `j ``in` `range``(N, ``0``, ``-``1``) :` `            ``# Update the dp table``            ``dp[j ``+` `1``][pre[i ``+` `1``] ``%` `(j ``+` `1``)] ``+``=` `dp[j][pre[i ``+` `1``] ``%` `j];` `            ``# If the last index is``            ``# reached, then add it``            ``# to the variable ans``            ``if` `(i ``=``=` `N ``-` `1``) :``                ``ans ``+``=` `dp[j][pre[i ``+` `1``] ``%` `j];``           ` `    ``# Return the possible count of``    ``# splitting of array into subarrays``    ``return` `ans;`  `# Driver Code``if` `__name__ ``=``=`  `"__main__"` `:` `    ``arr ``=` `[ ``1``, ``2``, ``3``, ``4` `];``    ``N ``=` `len``(arr);` `    ``print``(countOfWays(arr, N));``    ` `    ``# This code is contributed by AnkThon`

## C#

 `// C# program for the above approach``using` `System;` `public` `class` `GFG``{``  ` `// Function to count ways to split``// an array into subarrays such that``// sum of the i-th subarray is``// divisible by i``static` `int` `countOfWays(``int``[] arr, ``int` `N)``{` `    ``// Stores the prefix sum of array``    ``int``[] pre = ``new` `int``[N + 1];``    ` `    ``for` `(``int` `i = 0; i < N; i++) {` `        ``// Find the prefix sum``        ``pre[i + 1] = pre[i] + arr[i];``    ``}` `    ``// Initialize dp[][] array``    ``int``[,] dp = ``new` `int` `[N + 2, N + 2];` `    ``dp[1, 0]++;` `    ``// Stores the count of splitting``    ``int` `ans = 0;` `    ``// Iterate over the range [0, N]``    ``for` `(``int` `i = 0; i < N; i++) {``        ``for` `(``int` `j = N; j >= 1; j--) {` `            ``// Update the dp table``            ``dp[j + 1, pre[i + 1] % (j + 1)]``                ``+= dp[j, pre[i + 1] % j];` `            ``// If the last index is``            ``// reached, then add it``            ``// to the variable ans``            ``if` `(i == N - 1) {``                ``ans += dp[j, pre[i + 1] % j];``            ``}``        ``}``    ``}` `    ``// Return the possible count of``    ``// splitting of array into subarrays``    ``return` `ans;``}` `  ``// Driver Code``  ``public` `static` `void` `Main(String []args) {``    ` `    ``int``[] arr = { 1, 2, 3, 4 };``    ``int` `N = arr.Length;``        ` `    ``Console.WriteLine(countOfWays(arr, N));``  ``}` `}` `// This code is contributed by sanjoy_62.`

## Javascript

 ``

Output

`3`

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

My Personal Notes arrow_drop_up