coderx
coderx

Reputation: 519

Count total subsequences whose sum is divisible by k

I am trying to write a DP solution for the problem: count total number of sub-sequences possible of an array whose elements' sum is divisible by k.

I have written the following solution. But it is not giving the correct result. Like in the following code snippet, the array is {1, 2, 1} and k = 3. So expected total number of sub sequences divisible by 3 is 2, but the actual result is 3 which is clearly incorrect.

Please point out my mistake.

private int countDP(int[] a, int k)
{
    int L = a.length;

    int[][] DP = new int[L][k];

    for(int i = 0; i < DP.length; i++)
    {
        for(int j = 0; j < DP[0].length; j++)
            DP[i][j] = -1;
    }

    int res = _countDP(a, k, DP, 0, 0);

    return res;
}

private int _countDP(int[] a, int k, int[][] DP, int idx, int m) //Not giving the correct result.
{
    if(idx == a.length)
        return m == 0 ? 1 : 0;

    if(DP[idx][m] != -1)
        return DP[idx][m];

    int ans = 0;

    ans = _countDP(a, k, DP, idx + 1, m);
    ans += _countDP(a, k, DP, idx + 1, (m + a[idx]) % k);

    return DP[idx][m] = ans;
}

public static void main(String[] args)
{
    CountSubnsequences cs = new CountSubnsequences();

    int[] a = {1, 2, 1};
    int k = 3;

    int total1 = cs.countDP(a, k);

    System.out.println("Total numeber of sub sequences: " + total1);
}

Upvotes: 2

Views: 7626

Answers (4)

Taukir Khatri
Taukir Khatri

Reputation: 1

Faced the same issue. But ended up getting an answer.

The answer returning will be always 1 more than the total possible subsequences. This is because we know that 0 is always being a valid answer. So, if let's say you do not pick any single element from the array, then also the sum=0. So, it considers it as a valid answer and increments our answer by 1. So, to get the actual answer Just decrement the returned value by 1.

Upvotes: 0

dilit
dilit

Reputation: 53

Python code of @piotrekg2 solution. Looks good!

from typing import List


# dp[i][j] = the number of subsequences of length i with remainder equal to j.
def count_subseq(s: List[int],k):
    n = len(s)
    dp = [0]*k
    dp[0] = 1  # i=0, remainder=0, only 1 subseq
    for i in range(1,n+1):
        dp2 = dp.copy()   # copy previous i-length results: results without s[i] in subseq
        for j in range(k):
            dp2[(j+s[i-1])%k] += dp[j]
        dp = dp2
    return dp[0]


if __name__ == '__main__':
    print(count_subseq([2,3,5,8],5))
    print(count_subseq([5,5,5],5))

Upvotes: 0

piotrekg2
piotrekg2

Reputation: 1257

Let s denote a sequence of length N, and K be a given divisor.

dp[i][j] = the number of subsequences of s[0..i] with remainder equal to j. We will compute dp for all 0 <= i < N and 0 <= j < K.

dp[i][j] = 0 for all  (i, j)

dp[0][0] += 1
dp[0][s[0] mod K] += 1

for i = 1 .. N - 1
    for j = 0 .. K - 1
        dp[i][j] = dp[i - 1][j]
    for j = 0 .. K - 1
        dp[i][(j + s[i]) mod K] += dp[i - 1][j]

The result is dp[N - 1][0]

Upvotes: 5

geek
geek

Reputation: 1

int fun(int i,int s)
{

    if(i==1){

        if(s-a[i]!=0 && (s-a[i])%k==0)
        return 1;
        else
            return 0;}
    else{
        if((s-a[i])%k==0){
            return 1+fun(i-1,s-a[i])+fun(i-1,s);
        }
        else{
            return fun(i-1,s-a[i])+fun(i-1,s);
        }
    }
}

Upvotes: -1

Related Questions