# Longest subsequence whose sum is divisible by a given number

• Difficulty Level : Hard
• Last Updated : 13 Aug, 2021

Given an array arr[] and an integer M, the task is to find the length of the longest subsequence whose sum is divisible by M. If there is no such sub-sequence then print 0
Examples:

Input: arr[] = {3, 2, 2, 1}, M = 3
Output:
Longest sub-sequence whose sum is
divisible by 3 is {3, 2, 1}
Input: arr[] = {2, 2}, M = 3
Output:

Approach: A simple way to solve this will be to generate all the possible sub-sequences and then find the largest among them divisible whose sum is divisible by M. However, for smaller values of M, a dynamic programming based approach can be used.
Let’s look at the recurrence relation first.

dp[i][curr_mod] = max(dp[i + 1][curr_mod], dp[i + 1][(curr_mod + arr[i]) % m] + 1)

Let’s understand the states of DP now. Here, dp[i][curr_mod] stores the longest subsequence of subarray arr[i…N-1] such that the sum of this subsequence and curr_mod is divisible by M. At each step, either index i can be chosen updating curr_mod or it can be ignored.
Also, note that only SUM % m needs to be stored instead of the entire sum as this information is sufficient to complete the states of DP.
Below is the implementation of the above approach:

## C++

 `// C++ implementation of the approach` `#include ` `using` `namespace` `std;` `#define maxN 20` `#define maxM 64`   `// To store the states of DP` `int` `dp[maxN][maxM];` `bool` `v[maxN][maxM];`   `// Function to return the length` `// of the longest subsequence` `// whose sum is divisible by m` `int` `findLen(``int``* arr, ``int` `i, ``int` `curr,` `            ``int` `n, ``int` `m)` `{` `    ``// Base case` `    ``if` `(i == n) {` `        ``if` `(!curr)` `            ``return` `0;` `        ``else` `            ``return` `-1;` `    ``}`   `    ``// If the state has been solved before` `    ``// return the value of the state` `    ``if` `(v[i][curr])` `        ``return` `dp[i][curr];`   `    ``// Setting the state as solved` `    ``v[i][curr] = 1;`   `    ``// Recurrence relation` `    ``int` `l = findLen(arr, i + 1, curr, n, m);` `    ``int` `r = findLen(arr, i + 1,` `                    ``(curr + arr[i]) % m, n, m);` `    ``dp[i][curr] = l;` `    ``if` `(r != -1)` `        ``dp[i][curr] = max(dp[i][curr], r + 1);` `    ``return` `dp[i][curr];` `}`   `// Driver code` `int` `main()` `{` `    ``int` `arr[] = { 3, 2, 2, 1 };` `    ``int` `n = ``sizeof``(arr) / ``sizeof``(``int``);` `    ``int` `m = 3;`   `    ``cout << findLen(arr, 0, 0, n, m);`   `    ``return` `0;` `}`

## Java

 `// Java implementation of the approach` `class` `GFG` `{`   `static` `int` `maxN = ``20``;` `static` `int` `maxM = ``64``;`   `// To store the states of DP` `static` `int` `[][]dp = ``new` `int``[maxN][maxM];` `static` `boolean` `[][]v = ``new` `boolean``[maxN][maxM];`   `// Function to return the length` `// of the longest subsequence` `// whose sum is divisible by m` `static` `int` `findLen(``int``[] arr, ``int` `i, ` `                   ``int` `curr, ``int` `n, ``int` `m)` `{` `    ``// Base case` `    ``if` `(i == n) ` `    ``{` `        ``if` `(curr == ``0``)` `            ``return` `0``;` `        ``else` `            ``return` `-``1``;` `    ``}`   `    ``// If the state has been solved before` `    ``// return the value of the state` `    ``if` `(v[i][curr])` `        ``return` `dp[i][curr];`   `    ``// Setting the state as solved` `    ``v[i][curr] = ``true``;`   `    ``// Recurrence relation` `    ``int` `l = findLen(arr, i + ``1``, curr, n, m);` `    ``int` `r = findLen(arr, i + ``1``,` `                   ``(curr + arr[i]) % m, n, m);` `    ``dp[i][curr] = l;` `    ``if` `(r != -``1``)` `        ``dp[i][curr] = Math.max(dp[i][curr], r + ``1``);` `    ``return` `dp[i][curr];` `}`   `// Driver code` `public` `static` `void` `main(String []args)` `{` `    ``int` `arr[] = { ``3``, ``2``, ``2``, ``1` `};` `    ``int` `n = arr.length;` `    ``int` `m = ``3``;`   `    ``System.out.println(findLen(arr, ``0``, ``0``, n, m));` `}` `}`   `// This code is contributed by 29AjayKumar`

## Python3

 `# Python3 implementation of the approach ` `import` `numpy as np`   `maxN ``=` `20` `maxM ``=` `64`   `# To store the states of DP ` `dp ``=` `np.zeros((maxN, maxM)); ` `v ``=` `np.zeros((maxN, maxM)); `   `# Function to return the length ` `# of the longest subsequence ` `# whose sum is divisible by m ` `def` `findLen(arr, i, curr, n, m) :` `    `  `    ``# Base case ` `    ``if` `(i ``=``=` `n) :` `        ``if` `(``not` `curr) :` `            ``return` `0``; ` `        ``else` `:` `            ``return` `-``1``; `   `    ``# If the state has been solved before ` `    ``# return the value of the state ` `    ``if` `(v[i][curr]) :` `        ``return` `dp[i][curr]; `   `    ``# Setting the state as solved ` `    ``v[i][curr] ``=` `1``; `   `    ``# Recurrence relation ` `    ``l ``=` `findLen(arr, i ``+` `1``, curr, n, m); ` `    ``r ``=` `findLen(arr, i ``+` `1``, ` `               ``(curr ``+` `arr[i]) ``%` `m, n, m); ` `    `  `    ``dp[i][curr] ``=` `l; ` `    ``if` `(r !``=` `-``1``) :` `        ``dp[i][curr] ``=` `max``(dp[i][curr], r ``+` `1``); ` `        `  `    ``return` `dp[i][curr]; `   `# Driver code ` `if` `__name__ ``=``=` `"__main__"` `: `   `    ``arr ``=` `[ ``3``, ``2``, ``2``, ``1` `]; ` `    ``n ``=` `len``(arr); ` `    ``m ``=` `3``; `   `    ``print``(findLen(arr, ``0``, ``0``, n, m));`   `# This code is contributed by AnkitRai`

## C#

 `// C# implementation of the approach` `using` `System;` `                    `  `class` `GFG ` `{` `    `  `static` `int` `maxN = 20;` `static` `int` `maxM = 64;`   `// To store the states of DP` `static` `int` `[,]dp = ``new` `int``[maxN, maxM];` `static` `Boolean [,]v = ``new` `Boolean[maxN, maxM];`   `// Function to return the length` `// of the longest subsequence` `// whose sum is divisible by m` `static` `int` `findLen(``int``[] arr, ``int` `i, ` `                   ``int` `curr, ``int` `n, ``int` `m)` `{` `    ``// Base case` `    ``if` `(i == n) ` `    ``{` `        ``if` `(curr == 0)` `            ``return` `0;` `        ``else` `            ``return` `-1;` `    ``}`   `    ``// If the state has been solved before` `    ``// return the value of the state` `    ``if` `(v[i, curr])` `        ``return` `dp[i, curr];`   `    ``// Setting the state as solved` `    ``v[i, curr] = ``true``;`   `    ``// Recurrence relation` `    ``int` `l = findLen(arr, i + 1, curr, n, m);` `    ``int` `r = findLen(arr, i + 1,` `                   ``(curr + arr[i]) % m, n, m);` `    ``dp[i, curr] = l;` `    ``if` `(r != -1)` `        ``dp[i, curr] = Math.Max(dp[i, curr], r + 1);` `    ``return` `dp[i, curr];` `}`   `// Driver code` `public` `static` `void` `Main(String []args)` `{` `    ``int` `[]arr = { 3, 2, 2, 1 };` `    ``int` `n = arr.Length;` `    ``int` `m = 3;`   `    ``Console.WriteLine(findLen(arr, 0, 0, n, m));` `}` `}`   `// This code is contributed by 29AjayKumar`

## Javascript

 ``

Output:

`3`

Time Complexity: O(N * M)
Auxiliary Space: O(N * M).

My Personal Notes arrow_drop_up
Recommended Articles
Page :