Count ways to split an array into subarrays such that sum of the i-th subarray is divisible by i
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:
- Split the array into subarray as {1}, {2}, {3}, {4} and the sum of each of the ith subarray is divisible by i.
- Split the array into subarray as {1, 2, 3}, {4} and each of the ith subarray is divisible by i.
- 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:
- 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).
- 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 <bits/stdc++.h>
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[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
int main()
{
int arr[] = { 1, 2, 3, 4 };
int N = sizeof(arr) / sizeof(arr[0]);
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
<script>
// Javascript program for the above approach
// Function to count ways to split
// an array into subarrays such that
// sum of the i-th subarray is
// divisible by i
function countOfWays(arr, N)
{
// Stores the prefix sum of array
let pre = new Array(N + 1).fill(0);
for (let i = 0; i < N; i++)
{
// Find the prefix sum
pre[i + 1] = pre[i] + arr[i];
}
// Initialize dp[][] array
let dp = new Array(N + 2).fill(0).map(() => new Array(N + 2).fill(0));
dp[1][0]++;
// Stores the count of splitting
let ans = 0;
// Iterate over the range [0, N]
for (let i = 0; i < N; i++) {
for (let 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
let arr = [1, 2, 3, 4];
let N = arr.length;
document.write(countOfWays(arr, N));
// This code is contributed by _Saurabh_Jaiswal
</script>
Time Complexity: O(N2)
Auxiliary Space: O(N2)
Similar Reads
Find a subarray whose sum is divisible by size of the array Given an array arr[] of length N. The task is to check if there exists any subarray whose sum is a multiple of N. If there exists such subarray, then print the starting and ending index of that subarray else print -1. If there are multiple such subarrays, print any of them. Examples: Input: arr[] =
13 min read
Count of ways to split an Array into three contiguous Subarrays having increasing Sum Given an array arr[] consisting of non-negative integers, the task is to find the number of ways to split the array into three non-empty contiguous subarrays such that their respective sum of elements are in increasing order. Examples: Input: arr[] = {2, 3, 1, 7} Output: 2 Explanation: {{2}, {3, 1},
7 min read
Generate an Array such that the sum of any Subarray is not divisible by its Length Given an integer N. Then the task is to output an array let's say A[] of length N such that: The sum S, of any subarray, let's say A[L, R] where (L != R) must not leave the remainder as 0 when dividing by the length of A[L, R]. Formally, Sum(A[L, R])%(length of A[L, R]) != 0. A[] must contain all un
5 min read
Ways to form an array having integers in given range such that total sum is divisible by 2 Given three positive integers N, L and R. The task is to find the number of ways to form an array of size N where each element lies in the range [L, R] such that the total sum of all the elements of the array is divisible by 2.Examples: Input: N = 2, L = 1, R = 3 Output: 5 Explanation: Possible arra
15+ min read
Subsequences of size three in an array whose sum is divisible by m Given an array A[] (1<=A_i <=10^9 ) of size N (1<=N<=10^5 ), find the number of subsequences of length 3 whose sum is divisible by M (1<=M<=10^3 ). Examples: Input : A[] = {1, 2, 4, 3} M = 3 Output : 2 Explanation : We can choose two such subsequence of length 3 such that its sum i
15+ min read