# Count number of increasing subsequences of size k

• Difficulty Level : Hard
• Last Updated : 13 Mar, 2023

Given an array arr[] containing n integers. The problem is to count number of increasing subsequences in the array of size k.

Examples:

```Input : arr[] = {2, 6, 4, 5, 7},
k = 3
Output : 5
The subsequences of size '3' are:
{2, 6, 7}, {2, 4, 5}, {2, 4, 7},
{2, 5, 7} and {4, 5, 7}.

Input : arr[] = {12, 8, 11, 13, 10, 15, 14, 16, 20},
k = 4
Output : 39```

Approach: The idea is to use Dynamic Programming by define 2D matrix, say dp[][]. dp[i][j] stores the count of increasing subsequences of size i ending with element arr[j]. So dp[i][j] can be defined as:

dp[i][j] = 1, where i = 1 and 1 <= j <= n
dp[i][j] = sum(dp[i-1][j]), where 1 < i <= k, i <= j <= n and arr[m] < arr[j] for (i-1) <= m < j.

Below is the implementation of above approach:

## C++

 `// C++ implementation to count number of``// increasing subsequences of size k``#include ` `using` `namespace` `std;` `// function to count number of increasing``// subsequences of size k``int` `numOfIncSubseqOfSizeK(``int` `arr[], ``int` `n, ``int` `k)``{``    ``int` `dp[k][n], sum = 0;``    ``memset``(dp, 0, ``sizeof``(dp));` `    ``// count of increasing subsequences of size 1``    ``// ending at each arr[i]``    ``for` `(``int` `i = 0; i < n; i++)``        ``dp[0][i] = 1;` `    ``// building up the matrix dp[][]``    ``// Here 'l' signifies the size of``    ``// increasing subsequence of size (l+1).``    ``for` `(``int` `l = 1; l < k; l++) {` `        ``// for each increasing subsequence of size 'l'``        ``// ending with element arr[i]``        ``for` `(``int` `i = l; i < n; i++) {` `            ``// count of increasing subsequences of size 'l'``            ``// ending with element arr[i]``            ``dp[l][i] = 0;``            ``for` `(``int` `j = l - 1; j < i; j++) {``                ``if` `(arr[j] < arr[i])``                    ``dp[l][i] += dp[l - 1][j];``            ``}``        ``}``    ``}` `    ``// sum up the count of increasing subsequences of``    ``// size 'k' ending at each element arr[i]``    ``for` `(``int` `i = k - 1; i < n; i++)``        ``sum += dp[k - 1][i];` `    ``// required number of increasing``    ``// subsequences of size k``    ``return` `sum;``}` `// Driver program to test above``int` `main()``{``    ``int` `arr[] = { 12, 8, 11, 13, 10, 15, 14, 16, 20 };``    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr[0]);``    ``int` `k = 4;` `    ``cout << ``"Number of Increasing Subsequences of size "``         ``<< k << ``" = "` `<< numOfIncSubseqOfSizeK(arr, n, k);` `    ``return` `0;``}`

## Java

 `//Java implementation to count number of``// increasing subsequences of size k` `class` `GFG {` `// function to count number of increasing``// subsequences of size k``    ``static` `int` `numOfIncSubseqOfSizeK(``int` `arr[], ``int` `n, ``int` `k) {``        ``int` `dp[][] = ``new` `int``[k][n], sum = ``0``;` `        ``// count of increasing subsequences of size 1``        ``// ending at each arr[i]``        ``for` `(``int` `i = ``0``; i < n; i++) {``            ``dp[``0``][i] = ``1``;``        ``}` `        ``// building up the matrix dp[][]``        ``// Here 'l' signifies the size of``        ``// increasing subsequence of size (l+1).``        ``for` `(``int` `l = ``1``; l < k; l++) {` `            ``// for each increasing subsequence of size 'l'``            ``// ending with element arr[i]``            ``for` `(``int` `i = l; i < n; i++) {` `                ``// count of increasing subsequences of size 'l'``                ``// ending with element arr[i]``                ``dp[l][i] = ``0``;``                ``for` `(``int` `j = l - ``1``; j < i; j++) {``                    ``if` `(arr[j] < arr[i]) {``                        ``dp[l][i] += dp[l - ``1``][j];``                    ``}``                ``}``            ``}``        ``}` `        ``// sum up the count of increasing subsequences of``        ``// size 'k' ending at each element arr[i]``        ``for` `(``int` `i = k - ``1``; i < n; i++) {``            ``sum += dp[k - ``1``][i];``        ``}` `        ``// required number of increasing``        ``// subsequences of size k``        ``return` `sum;``    ``}` `// Driver program to test above``    ``public` `static` `void` `main(String[] args) {``        ``int` `arr[] = {``12``, ``8``, ``11``, ``13``, ``10``, ``15``, ``14``, ``16``, ``20``};``        ``int` `n = arr.length;``        ``int` `k = ``4``;` `        ``System.out.print(``"Number of Increasing Subsequences of size "``                ``+ k + ``" = "` `+ numOfIncSubseqOfSizeK(arr, n, k));` `    ``}``}``// This code is contributed by 29AjayKumar`

## Python3

 `# Python3 implementation to count number``# of increasing subsequences of size k``import` `math as mt` `# function to count number of increasing``# subsequences of size k``def` `numOfIncSubseqOfSizeK(arr, n, k):` `    ``dp ``=` `[[``0` `for` `i ``in` `range``(n)]``             ``for` `i ``in` `range``(k)]``             ` `    ``# count of increasing subsequences``    ``# of size 1 ending at each arr[i]``    ``for` `i ``in` `range``(n):``        ``dp[``0``][i] ``=` `1` `    ``# building up the matrix dp[][]``    ``# Here 'l' signifies the size of``    ``# increasing subsequence of size (l+1).``    ``for` `l ``in` `range``(``1``, k):` `        ``# for each increasing subsequence of``        ``# size 'l' ending with element arr[i]``        ``for` `i ``in` `range``(l, n):` `            ``# count of increasing subsequences of``            ``# size 'l' ending with element arr[i]``            ``dp[l][i] ``=` `0``            ``for` `j ``in` `range``(l ``-` `1``, i):``                ``if` `(arr[j] < arr[i]):``                    ``dp[l][i] ``+``=` `dp[l ``-` `1``][j]``            ` `    ``# Sum up the count of increasing subsequences``    ``# of size 'k' ending at each element arr[i]``    ``Sum` `=` `0``    ``for` `i ``in` `range``(k ``-` `1``, n):``        ``Sum` `+``=` `dp[k ``-` `1``][i]` `    ``# required number of increasing``    ``# subsequences of size k``    ``return` `Sum` `# Driver Code``arr ``=` `[``12``, ``8``, ``11``, ``13``, ``10``,``          ``15``, ``14``, ``16``, ``20` `]``n ``=` `len``(arr)``k ``=` `4` `print``(``"Number of Increasing Subsequences of size"``,``         ``k, ``"="``, numOfIncSubseqOfSizeK(arr, n, k))` `# This code is contributed by``# Mohit kumar 29`

## C#

 `// C# implementation to count number of``// increasing subsequences of size k`` ` `using` `System;``                    ` `public` `class` `GFG {`` ` `// function to count number of increasing``// subsequences of size k``    ``static` `int` `numOfIncSubseqOfSizeK(``int` `[]arr, ``int` `n, ``int` `k) {``        ``int` `[,]dp = ``new` `int``[k,n]; ``int` `sum = 0;`` ` `        ``// count of increasing subsequences of size 1``        ``// ending at each arr[i]``        ``for` `(``int` `i = 0; i < n; i++) {``            ``dp[0,i] = 1;``        ``}`` ` `        ``// building up the matrix dp[,]``        ``// Here 'l' signifies the size of``        ``// increasing subsequence of size (l+1).``        ``for` `(``int` `l = 1; l < k; l++) {`` ` `            ``// for each increasing subsequence of size 'l'``            ``// ending with element arr[i]``            ``for` `(``int` `i = l; i < n; i++) {`` ` `                ``// count of increasing subsequences of size 'l'``                ``// ending with element arr[i]``                ``dp[l,i] = 0;``                ``for` `(``int` `j = l - 1; j < i; j++) {``                    ``if` `(arr[j] < arr[i]) {``                        ``dp[l,i] += dp[l - 1,j];``                    ``}``                ``}``            ``}``        ``}`` ` `        ``// sum up the count of increasing subsequences of``        ``// size 'k' ending at each element arr[i]``        ``for` `(``int` `i = k - 1; i < n; i++) {``            ``sum += dp[k - 1,i];``        ``}`` ` `        ``// required number of increasing``        ``// subsequences of size k``        ``return` `sum;``    ``}`` ` `// Driver program to test above``    ``public` `static` `void` `Main() {``        ``int` `[]arr = {12, 8, 11, 13, 10, 15, 14, 16, 20};``        ``int` `n = arr.Length;``        ``int` `k = 4;`` ` `        ``Console.Write(``"Number of Increasing Subsequences of size "``                ``+ k + ``" = "` `+ numOfIncSubseqOfSizeK(arr, n, k));`` ` `    ``}``}``// This code is contributed by 29AjayKumar`

## PHP

 ``

## Javascript

 ``

Output

`Number of Increasing Subsequences of size 4 = 39`

Time Complexity: O(kn2).
Auxiliary Space: O(kn).

## Segment Tree Approach

For every element arr[i], we need to search for all arr[i]-1 as these are the elements that can be appended to arr[i] to make increasing subsequence. This is very much similar to COUNT LONGEST INCREASING SUBSEQUENCES. We use a vector of size K for each node in segment Tree signifying the length of LIS of size K ending at node.

Stepping down the array to smaller numbers with same ordering will reduce the space complexity as well.

If arr[i] has vector K={1,3,2}, signifies there is   one K=1 length LIS ending at arr[i]

three K=2 length LIS ending at arr[i]

two K=3 length LIS ending at arr[i]

If arr[j] is greater than arr[i], then arr[j] can appended after arr[i]. So the vector of arr[j] becomes {1,1,3}.

The K=1 remains the same since every element itself is a single length(K=1) subsequence.

We will take subsequences of length K=1 from arr[i] in the K=2 of arr[j] Since all the K=1 increasing subsequences of arr[i] becomes K=2 length increasing subsequences when arr[j] is added to arr[i].

Similarly all the K=2 length subsequences of arr[i] becomes K=3 length subsequences for arr[j] as arr[j] gets appended to K=2 subsequences of arr[i]. We are not adding here, because we are calculating ways, not length.

## Simply saying vec_j[K]=vec_i[K-1], where K>1

Below is the implementation of above approach:

## C++

 `#include ``using` `namespace` `std;` `vector>tree; ``/* vector represents the number of ways``                                  ``LIS of size K ending at node can be formed */` `int` `RANKER(vector<``int``>& arr) {``    ``int` `n = arr.size();` `    ``vector<``int``> temp = arr;``    ``sort(temp.begin(), temp.end());` `    ``unordered_map<``int``, ``int``> mpp;``    ``int` `mx = 0;` `    ``for` `(``int` `i = 0; i < n; i++) {``        ``if` `(mpp.find(temp[i]) == mpp.end()) {``            ``mpp[temp[i]] = mx;``            ``mx++;``        ``}``    ``}``    ``for` `(``int` `i = 0; i < n; i++) {``        ``arr[i] = mpp[arr[i]];``    ``}``    ``return` `mx;``}` `vector<``long` `long``> summation(vector<``long` `long``>& left, vector<``long` `long``>& right, ``int` `k) {``    ``// ADD WAYS, REMEMBER NO NEED TO TAKE MAX, WE ARE FINDING WAYS, NOT LENGTH.``    ``// So each K will contribute to final answer``    ``vector<``long` `long``> res(k + 1, 0);``    ``for` `(``int` `i = 1; i <= k; i++) {``        ``res[i] = left[i] + right[i];``    ``}``    ``return` `res;``}` `vector<``long` `long``> query(``int` `start, ``int` `end, ``int` `parent, ``int` `qstart, ``int` `qend, ``int` `k) {``    ``if` `(end < qstart || qend < start) {``        ``return` `vector<``long` `long``>(k + 1, 0);``    ``}``    ``if` `(qstart <= start && qend >= end) {``        ``return` `tree[parent];``    ``}``    ``int` `mid = (start + end) / 2;``    ``vector<``long` `long``> left = query(start, mid, 2 * parent + 1, qstart, qend, k);``    ``vector<``long` `long``> right = query(mid + 1, end, 2 * parent + 2, qstart, qend, k);``    ``return` `summation(left, right, k);``}` `void` `update(``int` `start, ``int` `end, ``int` `parent, ``int` `index, vector<``long` `long``>& updateThis, ``int` `k) {``    ``if` `(index < start || index > end) {``        ``return``;``    ``}``    ``if` `(start == end) {``        ``tree[parent] = summation(updateThis, tree[parent], k);``        ``return``;``    ``}``    ``int` `mid = (start + end) / 2;``    ``if` `(index > mid) {``        ``update(mid + 1, end, 2 * parent + 2, index, updateThis, k);``    ``}``    ``else` `{``        ``update(start, mid, 2 * parent + 1, index, updateThis, k);``    ``}``    ``vector<``long` `long``> left = tree[2 * parent + 1];``    ``vector<``long` `long``> right = tree[2 * parent + 2];``    ``tree[parent] = summation(left, right, k);``    ``return``;``}` `int` `numOfIncSubseqOfSizeK(vector<``int``>& arr, ``int` `K) {``    ``int` `n = arr.size();` `    ``int` `mx = RANKER(arr);` `    ``tree.resize(4 * mx + 1, vector<``long` `long``>(K + 1, 0));` `    ``for` `(``int` `i = 0; i < n; i++) {``        ``vector<``long` `long``> Kj(K + 1, 0); ``// K length ways``        ``Kj[1] = 1; ``// K=1 is element itself``      ` `        ``if` `(arr[i] > 0) { ``// arr[0] cannot be queried, since its the lowest``          ` `          ``/* Querying the longest LIS K array where arr[i] can append to*/``            ``vector<``long` `long``> Ki = query(0, mx, 0, 0, arr[i] - 1, K);` `              ``for` `(``int` `k = 2; k <= K; k++) { ``// As explained before``                ``Kj[k] = Ki[k - 1];``            ``}``        ``}``      ` `        ``update(0, mx, 0, arr[i], Kj, K); ``// update Kj array for arr[i]``    ``}``    ``return` `tree[0][K]; ``// answer is at kth index of root's K array``}` `int` `main() {``    ``vector<``int``> arr = { 12, 8, 11, 13, 10, 15, 14, 16, 20 };``    ``int` `k = 4;``    ``cout << ``"Number of Increasing Subsequences of size "``         ``<< k << ``" = "` `<< numOfIncSubseqOfSizeK(arr, k);``    ``return` `0;``}` `// Code by RainX (ABHIJIT ROY, NIT AGARTALA)`

Output

`Number of Increasing Subsequences of size 4 = 39`

Time Complexity: O(n*K*logn). For each index, we need to do query(logn) and update in K array(k)
Auxiliary Space: O(kn).

My Personal Notes arrow_drop_up