Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

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

  • Difficulty Level : Expert
  • Last Updated : 07 May, 2021

Given a 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:  

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

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



Input: N = 2 
Output:
Explanation: 
In the following two ways the ranks can be distributed among two students: 
The high scoring student can be awarded the first rank and the low scoring student the second rank or both of them can be awarded the same rank if they have equal scores. 

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

  • A bell number is a number that counts the possible partitions of a set. Therefore, an N-th bell number is a number of non-empty subsets a set of size N can be partitioned into.
  • For example, let’s consider the set {1, 2, 3} for N = 3. The bell number corresponding to N = 3 is 5. This signifies that the given set can be partitioned into following 5 non-empty subsets:
{{1}, {2}, {3}}
{{1, 2}, {3}}
{{1, 3}, {2}}
{{2, 3}, {1}}
{{1, 2, 3}}
  • Clearly, the above bell numbers signify all the possible ranks. However, they do not calculate the permutations of the subset.
  • Therefore, by multiplying every subset with K!, where K denotes the size of the respective subset, we get all the possible arrangements.
  • As the same subproblems can be repeated, we can store the values of each subproblem in a data structure to optimize the complexity.

Below is the implementation of the above approach: 

C++




// 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




// 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




# 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#




// 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

Javascript




<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

 




My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!