# Number of permutation with K inversions

• Difficulty Level : Hard
• Last Updated : 22 Jul, 2022

Given an array, an inversion is defined as a pair a[i], a[j] such that a[i] > a[j] and i < j. We are given two numbers N and k, we need to tell how many permutations of the first N number have exactly K inversion.

Examples:

```Input  : N = 3, K = 1
Output : 2
Explanation :
Total Permutation of first N number,
123, 132, 213, 231, 312, 321
Permutation with 1 inversion : 132 and 213

Input  : N = 4, K = 2
Output : 5```

A Naïve way to solve this problem is noting down all permutations then checking the count of inversion in them but iterating through permutation itself will take O(N!) time, which is too large.

We can solve this problem using a dynamic programming approach. Below is the recursive formula.

```If N is 0, Count(0, K) = 0

If K is 0, Count(N, 0) = 1 (Only sorted array)

In general case,
If we have N number and require K inversion,
Count(N, K) = Count(N - 1, K) +
Count(N – 1, K - 1) +
Count(N – 1, K – 2) +
.... +
Count(N – 1, 0)```

How does the above recursive formula work?
If we have N number and want to have K permutation and suppose all permutation of (N – 1) number are written somewhere, the new number (Nth number and largest) need to be placed in all permutation of (N – 1) number and those whose inversion count becomes K after adding this number should be added in our answer. Now take those sets of permutation of (N – 1) number which has let (K – 3) inversion, now we can place this new largest number at position 3 from last, then inversion count will be K, so count(N – 1, K – 3) should be added to our answer, the same argument can be given for another inversion also and we will reach to above recursion as the final answer.

The below code is written following the above recursion in a memorization way.

## C++

 `// C++ program to find number of permutation``// with K inversion using Memoization``#include ``using` `namespace` `std;` `// Limit on N and K``const` `int` `M = 100;` `// 2D array memo for stopping``// solving same problem again``int` `memo[M][M];` `// method recursively calculates``// permutation with K inversion``int` `numberOfPermWithKInversion(``int` `N, ``int` `K)``{``    ` `    ``// base cases``    ``if` `(N == 0)``        ``return` `0;``    ``if` `(K == 0)``        ``return` `1;` `    ``// if already solved then``    ``// return result directly``    ``if` `(memo[N][K] != 0)``        ``return` `memo[N][K];` `    ``// calling recursively all subproblem``    ``// of permutation size N - 1``    ``int` `sum = 0;``    ``for` `(``int` `i = 0; i <= K; i++)``    ``{` `        ``// Call recursively only``        ``// if total inversion``        ``// to be made are less``        ``// than size``        ``if` `(i <= N - 1)``            ``sum += numberOfPermWithKInversion(N - 1,``                                              ``K - i);``    ``}` `    ``// store result into memo``    ``memo[N][K] = sum;` `    ``return` `sum;``}` `// Driver code``int` `main()``{``    ``int` `N = 4;``    ``int` `K = 2;``    ``cout << numberOfPermWithKInversion(N, K);``    ``return` `0;``}`

## Java

 `// Java program to find number of permutation with``// K inversion using Memoization` `import` `java.io.*;` `class` `GFG {``    ` `    ``// Limit on N and K``    ``static` `int` `M = ``100``;` `    ``// 2D array memo for stopping solving same problem``    ``// again``    ``static` `int` `memo[][] = ``new` `int``[M][M];` `    ``// method recursively calculates permutation with``    ``// K inversion``    ``static` `int` `numberOfPermWithKInversion(``int` `N, ``int` `K)``    ``{``        ` `        ``// base cases``        ``if` `(N == ``0``)``            ``return` `0``;``        ``if` `(K == ``0``)``            ``return` `1``;` `        ``// if already solved then return result directly``        ``if` `(memo[N][K] != ``0``)``            ``return` `memo[N][K];` `        ``// calling recursively all subproblem of``        ``// permutation size N - 1``        ``int` `sum = ``0``;``        ``for` `(``int` `i = ``0``; i <= K; i++) {``            ` `            ``// Call recursively only if total inversion``            ``// to be made are less than size``            ``if` `(i <= N - ``1``)``                ``sum += numberOfPermWithKInversion(N - ``1``,``                                                  ``K - i);``        ``}` `        ``// store result into memo``        ``memo[N][K] = sum;` `        ``return` `sum;``    ``}` `    ``// Driver code to test above methods``    ``public` `static` `void` `main(String[] args)``    ``{``        ``int` `N = ``4``;``        ``int` `K = ``2``;``        ``System.out.println(numberOfPermWithKInversion(N, K));``    ``}``}` `// This code is contributed by vt_m.`

## Python3

 `# Python3 program to find number of permutation``# with K inversion using Memoization` `# Limit on N and K``M ``=` `100` `# 2D array memo for stopping ``# solving same problem again``memo ``=` `[[``0` `for` `i ``in` `range``(M)] ``for` `j ``in` `range``(M)]`` ` `# method recursively calculates``# permutation with K inversion``def` `numberOfPermWithKInversion(N, K):` `    ``# Base cases``    ``if` `(N ``=``=` `0``): ``return` `0``    ``if` `(K ``=``=` `0``): ``return` `1` `    ``# If already solved then``    ``# return result directly``    ``if` `(memo[N][K] !``=` `0``):``        ``return` `memo[N][K]` `    ``# Calling recursively all subproblem``    ``# of permutation size N - 1``    ``sum` `=` `0``    ``for` `i ``in` `range``(K ``+` `1``):``    ` `        ``# Call recursively only if``        ``# total inversion to be made``        ``# are less than size``        ``if` `(i <``=` `N ``-` `1``):``            ``sum` `+``=` `numberOfPermWithKInversion(N ``-` `1``, K ``-` `i)``    ` `    ``# store result into memo``    ``memo[N][K] ``=` `sum` `    ``return` `sum` `# Driver code``N ``=` `4``; K ``=` `2``print``(numberOfPermWithKInversion(N, K))` `# This code is contributed by Anant Agarwal.`

## C#

 `// C# program to find number of``// permutation with K inversion``// using Memoization``using` `System;` `class` `GFG``{` `// Limit on N and K``static` `int` `M = 100;` `// 2D array memo for stopping``// solving same problem again``static` `int` `[,]memo = ``new` `int``[M, M];` `// method recursively calculates``// permutation with K inversion``static` `int` `numberOfPermWithKInversion(``int` `N,``                                      ``int` `K)``{``    ` `    ``// base cases``    ``if` `(N == 0)``        ``return` `0;``    ``if` `(K == 0)``        ``return` `1;` `    ``// if already solved then``    ``// return result directly``    ``if` `(memo[N, K] != 0)``        ``return` `memo[N, K];` `    ``// calling recursively all``    ``// subproblem of permutation``    ``// size N - 1``    ``int` `sum = 0;``    ``for` `(``int` `i = 0; i <= K; i++)``    ``{``        ` `        ``// Call recursively only if``        ``// total inversion to be``        ``// made are less than size``        ``if` `(i <= N - 1)``            ``sum += numberOfPermWithKInversion(N - 1,``                                              ``K - i);``    ``}` `    ``// store result into memo``    ``memo[N, K] = sum;` `    ``return` `sum;``}` `// Driver Code``static` `public` `void` `Main ()``{``    ``int` `N = 4;``    ``int` `K = 2;``    ``Console.WriteLine(numberOfPermWithKInversion(N, K));``}``}` `// This code is contributed by ajit`

## PHP

 ``

## Javascript

 ``

Output

`5`

Time Complexity: O(N*N*K)

Space Complexity: O(N*K)

Optimized Approach: Using Tabulation and cumulative sum

## C++

 `// C++ program to find number of permutation``// with K inversions` `#include ``using` `namespace` `std;` `int` `numberOfPermWithKInversions(``int` `N, ``int` `K) {``    ``vector> dp(N+1,vector<``int``>(K+1));``  ` `    ``// As for k=0, number of permutations is 1 for every N``      ``for``(``int` `i = 1; i <= N; i++)``        ``dp[i] = 1;` `      ``// Using Dynamic Programming with cumulative sum``    ``for``(``int` `i = 1; i <= N; i++)``    ``{``        ``for``(``int` `j = 1; j <= K; j++)``        ``{``              ``// This is same as val = dp[i-1][j] - dp[i-1][j-i]``              ``// i.e. dp[i-1][j........j-i], just taking care of``              ``// boundaries``            ``int` `val = dp[i-1][j];``            ``if``(j >= i)``                ``val -= dp[i-1][j-i];` `            ``dp[i][j] = dp[i][j-1] + val;``        ``}``    ``}``  ` `      ``// And, in the end calculate the dp[n][k]``      ``// which is dp[n][k]-dp[n][k-1]``    ``int` `ans = dp[N][K];``    ``if``(K >= 1)``        ``ans -= dp[N][K-1];` `    ``return` `ans;``}` `int` `main() {``    ``int` `N = 4;``    ``int` `K = 2;``    ` `      ``cout << numberOfPermWithKInversions(N,K) << ``"\n"``;``    ``return` `0;``}`

## Java

 `/*package whatever //do not write package name here */` `import` `java.io.*;` `class` `GFG {``    ``static` `int` `numberOfPermWithKInversion(``int` `N, ``int` `K)``    ``{``       ``int``[][] dp = ``new` `int``[N + ``1``][K + ``1``];``       ``for``(``int` `i = ``1``; i <= N; i++)``        ``dp[i][``0``] = ``1``;` `    ``for``(``int` `i = ``1``; i <= N; i++)``    ``{``        ``for``(``int` `j = ``1``; j <= K; j++)``        ``{``              ``// boundaries``            ``int` `val = dp[i-``1``][j];``            ``if``(j >= i)``                ``val -= dp[i-``1``][j-i];`` ` `            ``dp[i][j] = dp[i][j-``1``] + val;``        ``}``    ``}``   ` `      ``// And, in the end calculate the dp[n][k]``      ``// which is dp[n][k]-dp[n][k-1]``    ``int` `ans = dp[N][K];``    ``if``(K >= ``1``)``        ``ans -= dp[N][K-``1``];`` ` `    ``return` `ans;``    ``}``  ` `    ``public` `static` `void` `main (String[] args) {``        ``int` `N = ``4``;``        ``int` `K = ``2``;``        ``System.out.println(numberOfPermWithKInversion(N, K));``    ``}``}`

Output

`5`

Time Complexity: O(N*K)

Space Complexity: O(N*K)
This article is contributed by Utkarsh Trivedi and Ankit Kumar Sharma. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

My Personal Notes arrow_drop_up