Open In App

Count the number of ways to give ranks for N students such that same ranks are possible

Given the number N which represents the number of students, the task is to calculate all possible ways to rank them according to their CGPA/marks, considering that two or more students can have the same rank. Since the answer can be large, perform the modulo with 109 + 7.

Examples:  



Input: N = 1 
Output:
Explanation: 
There is only one way to rank a student, irrespective of his marks. 

Input: N = 2 
Output: 3
Explanation: 
First way : if A and B student Got same marks, then Let say A has got higher rank than B .
Second Way :  if A and B student Got same marks, then Let say B has got higher rank than A .
Third way: If both got different, Then the person got higher mark , will get higher rank.



Approach: The idea for this problem is to use the Bell Numbers.  

{{1}, {2}, {3}}
{{1, 2}, {3}}
{{1, 3}, {2}}
{{2, 3}, {1}}
{{1, 2, 3}}

Implementation:




// C++ program to calculate the number
// of ways to give ranks for N
// students such that same ranks
// are possible
 
#include <bits/stdc++.h>
using namespace std;
 
const int mod = 1e9 + 7;
 
// Initializing a table in order to
// store the bell triangle
vector<vector<int> > dp;
 
// Function to calculate the K-th
// bell number
int f(int n, int k)
{
    // If we have already calculated
    // the bell numbers until the
    // required N
    if (n < k)
        return 0;
 
    // Base case
    if (n == k)
        return 1;
 
    // First Bell Number
    if (k == 1)
        return 1;
 
    // If the value of the bell
    // triangle has already been
    // calculated
    if (dp[n][k] != -1)
        return dp[n][k];
 
    // Fill the defined dp table
    return dp[n][k] = ((k * f(n - 1, k)) % mod
                       + (f(n - 1, k - 1)) % mod)
                      % mod;
}
 
// Function to return the number
// of ways to give ranks for N
// students such that same ranks
// are possible
long operation(int n)
{
    // Resizing the dp table for the
    // given value of n
    dp.resize(n + 1, vector<int>(n + 1, -1));
 
    // Variables to store the answer
    // and the factorial value
    long ans = 0, fac = 1;
 
    // Iterating till N
    for (int k = 1; k <= n; k++) {
 
        // Simultaneously calculate the k!
        fac *= k;
 
        // Computing the K-th bell number
        // and multiplying it with K!
        ans = (ans + (fac * f(n, k)) % mod)
              % mod;
    }
    return ans;
}
 
// Driver code
int main()
{
    int n = 5;
 
    cout << operation(n) << endl;
 
    return 0;
}




// Java program to calculate the number
// of ways to give ranks for N
// students such that same ranks
// are possible
import java.util.*;
 
class GFG{
 
static int mod = (int)(1e9 + 7);
 
// Initializing a table in order to
// store the bell triangle
static int [][]dp;
 
// Function to calculate the K-th
// bell number
static int f(int n, int k)
{
     
    // If we have already calculated
    // the bell numbers until the
    // required N
    if (n < k)
        return 0;
 
    // Base case
    if (n == k)
        return 1;
 
    // First Bell Number
    if (k == 1)
        return 1;
 
    // If the value of the bell
    // triangle has already been
    // calculated
    if (dp[n][k] != -1)
        return dp[n][k];
 
    // Fill the defined dp table
    return dp[n][k] = ((k * f(n - 1, k)) % mod +
                       (f(n - 1, k - 1)) % mod) % mod;
}
 
// Function to return the number
// of ways to give ranks for N
// students such that same ranks
// are possible
static long operation(int n)
{
     
    // Resizing the dp table for the
    // given value of n
    dp = new int[n + 1][n + 1];
    for(int i = 0; i < n + 1; i++)
    {
       for(int j = 0; j < n + 1; j++)
       {
          dp[i][j] = -1;
       }
    }
     
    // Variables to store the answer
    // and the factorial value
    long ans = 0, fac = 1;
 
    // Iterating till N
    for(int k = 1; k <= n; k++)
    {
        
       // Simultaneously calculate the k!
       fac *= k;
        
       // Computing the K-th bell number
       // and multiplying it with K!
       ans = (ans + (fac * f(n, k)) % mod) % mod;
    }
    return ans;
}
 
// Driver code
public static void main(String[] args)
{
    int n = 5;
 
    System.out.print(operation(n) + "\n");
}
}
 
// This code is contributed by amal kumar choubey




# Python3 program to calculate the number
# of ways to give ranks for N
# students such that same ranks
# are possible
mod = 1e9 + 7
 
# Initializing a table in order to
# store the bell triangle
dp = [[-1 for x in range(6)]
          for y in range(6)]
 
# Function to calculate the K-th
# bell number
def f(n, k):
     
    # If we have already calculated
    # the bell numbers until the
    # required N
    if (n < k):
        return 0
 
    # Base case
    if (n == k):
        return 1
 
    # First Bell Number
    if (k == 1):
        return 1
 
    # If the value of the bell
    # triangle has already been
    # calculated
    if (dp[n][k] != -1):
        return dp[n][k]
 
    # Fill the defined dp table
    dp[n][k] = ((((k * f(n - 1, k)) % mod +
               (f(n - 1, k - 1)) % mod) % mod))
    return dp[n][k]
 
# Function to return the number
# of ways to give ranks for N
# students such that same ranks
# are possible
def operation(n):
 
    # Resizing the dp table for the
    # given value of n
    global dp
 
    # Variables to store the answer
    # and the factorial value
    ans = 0
    fac = 1
 
    # Iterating till N
    for k in range(1, n + 1):
 
        # Simultaneously calculate the k!
        fac *= k
 
        # Computing the K-th bell number
        # and multiplying it with K!
        ans = (ans + (fac * f(n, k)) % mod) % mod
         
    return ans
 
# Driver code
if __name__ == "__main__":
 
    n = 5
 
    print(int(operation(n)))
 
# This code is contributed by ukasp




// C# program to calculate the number
// of ways to give ranks for N
// students such that same ranks
// are possible
using System;
 
class GFG{
 
static int mod = (int)(1e9 + 7);
 
// Initializing a table in order to
// store the bell triangle
static int [,]dp;
 
// Function to calculate the K-th
// bell number
static int f(int n, int k)
{
     
    // If we have already calculated
    // the bell numbers until the
    // required N
    if (n < k)
        return 0;
 
    // Base case
    if (n == k)
        return 1;
 
    // First Bell Number
    if (k == 1)
        return 1;
 
    // If the value of the bell
    // triangle has already been
    // calculated
    if (dp[n, k] != -1)
        return dp[n, k];
 
    // Fill the defined dp table
    return dp[n, k] = ((k * f(n - 1, k)) % mod +
                       (f(n - 1, k - 1)) % mod) % mod;
}
 
// Function to return the number
// of ways to give ranks for N
// students such that same ranks
// are possible
static long operation(int n)
{
     
    // Resizing the dp table for the
    // given value of n
    dp = new int[n + 1, n + 1];
    for(int i = 0; i < n + 1; i++)
    {
       for(int j = 0; j < n + 1; j++)
       {
          dp[i, j] = -1;
       }
    }
     
    // Variables to store the answer
    // and the factorial value
    long ans = 0, fac = 1;
 
    // Iterating till N
    for(int k = 1; k <= n; k++)
    {
        
       // Simultaneously calculate the k!
       fac *= k;
        
       // Computing the K-th bell number
       // and multiplying it with K!
       ans = (ans + (fac * f(n, k)) % mod) % mod;
    }
    return ans;
}
 
// Driver code
public static void Main(String[] args)
{
    int n = 5;
 
    Console.Write(operation(n) + "\n");
}
}
 
// This code is contributed by amal kumar choubey




<script>
 
// Javascript program to calculate the number
// of ways to give ranks for N
// students such that same ranks
// are possible
 
    var mod = parseInt( 1e9 + 7);
 
    // Initializing a table in order to
    // store the bell triangle
    var dp;
 
    // Function to calculate the K-th
    // bell number
    function f(n , k) {
 
        // If we have already calculated
        // the bell numbers until the
        // required N
        if (n < k)
            return 0;
 
        // Base case
        if (n == k)
            return 1;
 
        // First Bell Number
        if (k == 1)
            return 1;
 
        // If the value of the bell
        // triangle has already been
        // calculated
        if (dp[n][k] != -1)
            return dp[n][k];
 
        // Fill the defined dp table
        return dp[n][k] = ((k * f(n - 1, k)) % mod +
        (f(n - 1, k - 1)) % mod) % mod;
    }
 
    // Function to return the number
    // of ways to give ranks for N
    // students such that same ranks
    // are possible
    function operation(n) {
 
        // Resizing the dp table for the
        // given value of n
        dp = Array(n + 1).fill().map(()
        =>Array(n + 1).fill(0));
        for (i = 0; i < n + 1; i++) {
            for (j = 0; j < n + 1; j++) {
                dp[i][j] = -1;
            }
        }
 
        // Variables to store the answer
        // and the factorial value
        var ans = 0, fac = 1;
 
        // Iterating till N
        for (k = 1; k <= n; k++) {
 
            // Simultaneously calculate the k!
            fac *= k;
 
            // Computing the K-th bell number
            // and multiplying it with K!
            ans = (ans + (fac * f(n, k)) % mod) % mod;
        }
        return ans;
    }
 
    // Driver code
     
        var n = 5;
 
        document.write(operation(n) + "\n");
 
// This code contributed by umadevi9616
 
</script>

Output: 
541

 

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

Efficient approach: Using DP Tabulation method ( Iterative approach )

The approach to solving this problem is the same but DP tabulation(bottom-up) method is better the Dp + memorization(top-down) because memorization method needs extra stack space of recursion calls.

Steps to solve this problem:

  1. Create a vector to store the solution of the subproblems.
  2. Initialize the table with base cases
  3. Fill up the table iteratively.
  4. Return the final solution

Implementation:




#include <bits/stdc++.h>
using namespace std;
 
const int mod = 1e9 + 7;
 
int operation(int n)
{
    vector<vector<int> > dp(n + 1, vector<int>(n + 1));
 
    // Initialize base cases
    for (int i = 0; i <= n; i++) {
        dp[i][0] = 0;
        dp[i][i] = 1;
    }
 
    // Fill the DP table in a bottom-up manner
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j < i; j++) {
            dp[i][j] = (j * dp[i - 1][j] + dp[i - 1][j - 1])
                       % mod;
        }
        dp[i][i] = 1;
    }
 
    // Calculate the answer using the DP table
    long ans = 0, fac = 1;
    for (int k = 1; k <= n; k++) {
        fac *= k;
        ans = (ans + (fac * dp[n][k]) % mod) % mod;
    }
 
    return ans;
}
 
// Driver code
int main()
{
    int n = 5;
    // function call
    cout << operation(n) << endl;
    return 0;
}




import java.util.*;
 
public class Main {
    static final int mod = 1000000007;
 
    static int operation(int n) {
        int[][] dp = new int[n+1][n+1];
 
        // Initialize base cases
        for (int i = 0; i <= n; i++) {
            dp[i][0] = 0;
            dp[i][i] = 1;
        }
 
        // Fill the DP table in a bottom-up manner
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j < i; j++) {
                dp[i][j] = (j * dp[i-1][j] + dp[i-1][j-1]) % mod;
            }
            dp[i][i] = 1;
        }
 
        // Calculate the answer using the DP table
        long ans = 0, fac = 1;
        for (int k = 1; k <= n; k++) {
            fac *= k;
            ans = (ans + (fac * dp[n][k]) % mod) % mod;
        }
 
        return (int)ans;
    }
 
    // Driver code
    public static void main(String[] args) {
        int n = 5;
        // function call
        System.out.println(operation(n));
    }
}




mod = 10**9 + 7
 
def operation(n):
    dp = [[0 for j in range(n+1)] for i in range(n+1)]
 
    # Initialize base cases
    for i in range(n+1):
        dp[i][0] = 0
        dp[i][i] = 1
 
    # Fill the DP table in a bottom-up manner
    for i in range(1, n+1):
        for j in range(1, i):
            dp[i][j] = (j * dp[i-1][j] + dp[i-1][j-1]) % mod
        dp[i][i] = 1
 
    # Calculate the answer using the DP table
    ans, fac = 0, 1
    for k in range(1, n+1):
        fac *= k
        ans = (ans + (fac * dp[n][k]) % mod) % mod
 
    return ans
 
# Driver code
n = 5
print(operation(n))




using System;
using System.Collections.Generic;
 
class Solution {
  static int mod = 1000000007;
 
  static int operation(int n)
  {
    // 2D array to store the DP values
    int[][] dp = new int[n + 1][];
 
    // Initialize base cases
    for (int i = 0; i <= n; i++) {
      dp[i] = new int[n + 1];
      dp[i][0] = 0;
      dp[i][i] = 1;
    }
 
    // Fill the DP table in a bottom-up manner
    for (int i = 1; i <= n; i++) {
      for (int j = 1; j < i; j++) {
        dp[i][j]
          = (j * dp[i - 1][j] + dp[i - 1][j - 1])
          % mod;
      }
      dp[i][i] = 1;
    }
 
    // Calculate the answer using the DP table
    long ans = 0, fac = 1;
    for (int k = 1; k <= n; k++) {
      fac *= k;
      ans = (ans + (fac * dp[n][k]) % mod) % mod;
    }
 
    return (int)ans;
  }
 
  // Driver code
  static void Main(string[] args)
  {
    int n = 5;
    // Function call
    Console.WriteLine(operation(n));
  }
}
// This code is contributed by user_dtewbxkn77n




const mod = 10**9 + 7;
 
function operation(n) {
    let dp = Array.from(Array(n+1), () => new Array(n+1).fill(0));
 
    // Initialize base cases
    for (let i = 0; i <= n; i++) {
        dp[i][0] = 0;
        dp[i][i] = 1;
    }
 
    // Fill the DP table in a bottom-up manner
    for (let i = 1; i <= n; i++) {
        for (let j = 1; j < i; j++) {
            dp[i][j] = (j * dp[i-1][j] + dp[i-1][j-1]) % mod;
        }
        dp[i][i] = 1;
    }
 
    // Calculate the answer using the DP table
    let ans = 0, fac = 1;
    for (let k = 1; k <= n; k++) {
        fac *= k;
        ans = (ans + (fac * dp[n][k]) % mod) % mod;
    }
 
    return ans;
}
 
// Driver code
let n = 5;
console.log(operation(n));

Output
541

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


Article Tags :