Open In App

Count subsequences having average of its elements equal to K

Given an array arr[] consisting of N integers and an integer K, the task is to count the number of subsequences of the given array with average K.

Examples:



Input: arr[] = {9, 7, 8, 9}, K = 8
Output: 5
Explanation: The subsequences having average 8 are {8}, {9, 7}, {7, 9}, {9, 7, 8}, {7, 8, 9}.

Input: arr[] = {5, 5, 1}, K = 4
Output: 0
Explanation: No such subsequence can be obtained



Naive Approach: The simplest approach to solve the problem is to use recursion. Follow the steps below to solve the problem:

  1. Two options are possible for each array element, i.e. either to include the current element in the sum or to exclude the current element in the sum and increase the current index for each recursive call.
  2. For both the above possibilities, return the number of subsequences with average K.
  3. The base case is to check if the last index has been reached or not. The average in the base case can be calculated by dividing the sum of array elements included in that subsequence.
  4. If the average is equal to K, then return 1. Otherwise, return 0.

Time Complexity: O(2N)
Auxiliary Space: O(N)

Efficient Approach: The above approach can be optimized using Dynamic Programming. Follow the steps below to solve the problem:

If ith element is included, then dp[i + 1][k + 1][s + arr[i]] += dp[i][k][s]
If ith element is excluded, then dp[i + 1][k][s] += dp[i][k][s]

Below is the implementation of the above approach:




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Stores the dp states
int dp[101][101][1001];
 
// Function to find the count of
// subsequences having average K
int countAverage(int n, int K, int* arr)
{
 
    // Base condition
    dp[0][0][0] = 1;
 
    // Three loops for three states
    for (int i = 0; i < n; i++) {
        for (int k = 0; k < n; k++) {
            for (int s = 0; s <= 1000; s++) {
 
                // Recurrence relation
                dp[i + 1][k + 1][s + arr[i]]
                    += dp[i][k][s];
                dp[i + 1][k][s] += dp[i][k][s];
            }
        }
    }
 
    // Stores the sum of dp[n][j][K*j]
    // all possible values of j with
    // average K and sum K * j
    int cnt = 0;
 
    // Iterate over the range [1, N]
    for (int j = 1; j <= n; j++) {
        cnt += dp[n][j][K * j];
    }
 
    // Return the final count
    return cnt;
}
 
// Driver Code
int main()
{
    int arr[] = { 9, 7, 8, 9 };
    int K = 8;
    int N = sizeof(arr) / sizeof(arr[0]);
    cout << countAverage(N, K, arr);
 
    return 0;
}




// Java program for the above approach
import java.util.*;
class GFG
{
 
// Stores the dp states
static int [][][]dp = new int[101][101][1001];
 
// Function to find the count of
// subsequences having average K
static int countAverage(int n, int K, int[] arr)
{
 
    // Base condition
    dp[0][0][0] = 1;
 
    // Three loops for three states
    for (int i = 0; i < n; i++)
    {
        for (int k = 0; k < n; k++)
        {
            for (int s = 0; s <= 100; s++)
            {
 
                // Recurrence relation
                dp[i + 1][k + 1][s + arr[i]]
                    += dp[i][k][s];
                dp[i + 1][k][s] += dp[i][k][s];
            }
        }
    }
 
    // Stores the sum of dp[n][j][K*j]
    // all possible values of j with
    // average K and sum K * j
    int cnt = 0;
 
    // Iterate over the range [1, N]
    for (int j = 1; j <= n; j++)
    {
        cnt += dp[n][j][K * j];
    }
 
    // Return the final count
    return cnt;
}
 
// Driver Code
public static void main(String[] args)
{
    int arr[] = { 9, 7, 8, 9 };
    int K = 8;
    int N = arr.length;
    System.out.print(countAverage(N, K, arr));
}
}
 
// This code is contributed by shikhasingrajput




# Python3 program for the above approach
 
# Stores the dp states
dp = [[[0 for i in range(1001)] for i in range(101)] for i in range(101)]
 
# Function to find the count of
# subsequences having average K
def countAverage(n, K, arr):
    global dp
    dp[0][0][0] = 1
 
    # Three loops for three states
    for i in range(n):
        for k in range(n):
            for s in range(100):
 
                # Recurrence relation
                dp[i + 1][k + 1][s + arr[i]] += dp[i][k][s]
                dp[i + 1][k][s] += dp[i][k][s]
 
    # Stores the sum of dp[n][j][K*j]
    # all possible values of j with
    # average K and sum K * j
    cnt = 0
 
    # Iterate over the range [1, N]
    for j in range(1, n + 1):
        cnt += dp[n][j][K * j]
 
    # Return the final count
    return cnt
 
# Driver Code
if __name__ == '__main__':
    arr= [9, 7, 8, 9]
    K = 8
    N = len(arr)
 
    print(countAverage(N, K, arr))
 
    # This code is contributed by mohit kumar 29.




// C# program for the above approach
using System;
public class GFG
{
 
// Stores the dp states
static int [,,]dp = new int[101, 101, 1001];
 
// Function to find the count of
// subsequences having average K
static int countAverage(int n, int K, int[] arr)
{
 
    // Base condition
    dp[0, 0, 0] = 1;
 
    // Three loops for three states
    for (int i = 0; i < n; i++)
    {
        for (int k = 0; k < n; k++)
        {
            for (int s = 0; s <= 100; s++)
            {
 
                // Recurrence relation
                dp[i + 1, k + 1, s + arr[i]]
                    += dp[i, k, s];
                dp[i + 1, k, s] += dp[i, k, s];
            }
        }
    }
 
    // Stores the sum of dp[n,j,K*j]
    // all possible values of j with
    // average K and sum K * j
    int cnt = 0;
 
    // Iterate over the range [1, N]
    for (int j = 1; j <= n; j++)
    {
        cnt += dp[n, j, K * j];
    }
 
    // Return the readonly count
    return cnt;
}
 
// Driver Code
public static void Main(String[] args)
{
    int []arr = { 9, 7, 8, 9 };
    int K = 8;
    int N = arr.Length;
    Console.Write(countAverage(N, K, arr));
}
}
 
// This code is contributed by 29AjayKumar




<script>
 
// JavaScript program for the above approach
 
// Stores the dp states
var dp = Array.from(Array(101), ()=> Array(101));
 
for(var i =0; i<101; i++)
        for(var j =0; j<101; j++)
            dp[i][j] = new Array(1001).fill(0);
 
 
// Function to find the count of
// subsequences having average K
function countAverage(n, K, arr)
{
 
    // Base condition
    dp[0][0][0] = 1;
 
    // Three loops for three states
    for (var i = 0; i < n; i++) {
        for (var k = 0; k < n; k++) {
            for (var s = 0; s <= 1000; s++) {
 
                // Recurrence relation
                dp[i + 1][k + 1][s + arr[i]]
                    += dp[i][k][s];
                dp[i + 1][k][s] += dp[i][k][s];
            }
        }
    }
 
    // Stores the sum of dp[n][j][K*j]
    // all possible values of j with
    // average K and sum K * j
    var cnt = 0;
 
    // Iterate over the range [1, N]
    for (var j = 1; j <= n; j++) {
        cnt += dp[n][j][K * j];
    }
 
    // Return the final count
    return cnt;
}
 
// Driver Code
var arr = [9, 7, 8, 9];
var K = 8;
var N = arr.length
document.write( countAverage(N, K, arr));
 
</script>

Output
5







Time Complexity: O(S*N2) where S is the sum of the array.
Auxiliary Space: O(S*N2) 

Efficient approach : Space optimization

In previous approach the current value dp[i][j][s] is only depend upon the current and previous row values of DP. So to optimize the space complexity we use a single 2D array to store the computations.

Implementation:




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the count of
// subsequences having average K
int countAverage(int n, int K, int* arr)
{
    // Initialize a 2D array with 0's
    int dp[101][1001] = {0};
 
    // Base condition
    dp[0][0] = 1;
 
    // Three loops for three states
    for (int i = 0; i < n; i++) {
        for (int k = n; k > 0; k--) {
            for (int s = 1000; s >= arr[i]; s--) {
 
                // Recurrence relation
                dp[k][s] += dp[k - 1][s - arr[i]];
            }
        }
    }
 
    // Stores the sum of dp[n][K*j]
    // for all possible values of j
    int cnt = 0;
 
    // Iterate over the range [1, N]
    for (int j = 1; j <= n; j++) {
        cnt += dp[j][K * j];
    }
 
    // Return the final count
    return cnt;
}
 
// Driver Code
int main()
{
    int arr[] = { 9, 7, 8, 9 };
    int K = 8;
    int N = sizeof(arr) / sizeof(arr[0]);
    cout << countAverage(N, K, arr);
 
    return 0;
}




public class CountAverageSubsequences {
 
    // Function to find the count of subsequences having
    // average K
    static int countAverage(int n, int K, int[] arr)
    {
        // Initialize a 2D array with 0's
        int[][] dp = new int[101][1001];
 
        // Base condition
        dp[0][0] = 1;
 
        // Three loops for three states
        for (int i = 0; i < n; i++) {
            for (int k = n; k > 0; k--) {
                for (int s = 1000; s >= arr[i]; s--) {
 
                    // Recurrence relation
                    dp[k][s] += dp[k - 1][s - arr[i]];
                }
            }
        }
 
        // Stores the sum of dp[n][K*j] for all possible
        // values of j
        int cnt = 0;
 
        // Iterate over the range [1, N]
        for (int j = 1; j <= n; j++) {
            cnt += dp[j][K * j];
        }
 
        // Return the final count
        return cnt;
    }
 
    // Main method
    public static void main(String[] args)
    {
        int[] arr = { 9, 7, 8, 9 };
        int K = 8;
        int N = arr.length;
        System.out.println(countAverage(N, K, arr));
    }
}




def count_average(n, K, arr):
    # Initialize a 2D list with 0's
    dp = [[0 for _ in range(1001)] for _ in range(101)]
 
    # Base condition
    dp[0][0] = 1
 
    # Three loops for three states
    for i in range(n):
        for k in range(n, 0, -1):
            for s in range(1000, arr[i] - 1, -1):
 
                # Recurrence relation
                dp[k][s] += dp[k - 1][s - arr[i]]
 
    # Stores the sum of dp[n][K*j]
    # for all possible values of j
    cnt = 0
 
    # Iterate over the range [1, N]
    for j in range(1, n + 1):
        cnt += dp[j][K * j]
 
    # Return the final count
    return cnt
 
# Driver Code
 
 
def main():
    arr = [9, 7, 8, 9]
    K = 8
    N = len(arr)
    print(count_average(N, K, arr))
 
 
if __name__ == "__main__":
    main()




using System;
 
class GFG {
  // Function to find the count of
 // subsequences having average K
    static int CountAverage(int n, int K, int[] arr)
    {
        // Initialize a 2D array with 0's
        int[, ] dp = new int[101, 1001];
 
        // Base condition
        dp[0, 0] = 1;
 
        // Three loops for three states
        for (int i = 0; i < n; i++) {
            for (int k = n; k > 0; k--) {
                for (int s = 1000; s >= arr[i]; s--) {
                    // Recurrence relation
                    dp[k, s] += dp[k - 1, s - arr[i]];
                }
            }
        }
 
        // Stores the sum of dp[n][K*j]
        // for all possible values of j
        int cnt = 0;
 
        // Iterate over the range [1, N]
        for (int j = 1; j <= n; j++) {
            cnt += dp[j, K * j];
        }
 
        // Return the final count
        return cnt;
    }
 
    static void Main(string[] args)
    {
        int[] arr = { 9, 7, 8, 9 };
        int K = 8;
        int N = arr.Length;
        Console.WriteLine(CountAverage(N, K, arr));
    }
}




function countAverage(N, K, arr) {
    // Initialize a 2D array with 0's
    const dp = new Array(101);
    for (let i = 0; i <= 100; i++) {
        dp[i] = new Array(1001).fill(0);
    }
 
    // Base condition
    dp[0][0] = 1;
 
    // Three loops for three states
    for (let i = 0; i < N; i++) {
        for (let k = N; k > 0; k--) {
            for (let s = 1000; s >= arr[i]; s--) {
                // Recurrence relation
                dp[k][s] += dp[k - 1][s - arr[i]];
            }
        }
    }
 
    // Stores the sum of dp[N][K*j]
    // for all possible values of j
    let cnt = 0;
 
    // Iterate over the range [1, N]
    for (let j = 1; j <= N; j++) {
        cnt += dp[j][K * j];
    }
 
    // Return the final count
    return cnt;
}
 
// Driver Code
const arr = [9, 7, 8, 9];
const K = 8;
const N = arr.length;
console.log(countAverage(N, K, arr));

Output
5

Time Complexity: O(S*N2) where S is the sum of the array.
Auxiliary Space: O(S*N) 


Article Tags :