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

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:  
Input: N = 1 Output: 1 Explanation: There is only one way to rank a student, irrespective of his marks. 
Input: N = 2 Output: 2 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++
Java
Python3
C#
Javascript
// 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 trianglevector<vector<int> > dp; // Function to calculate the K-th// bell numberint 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 possiblelong 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 codeint 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 possibleimport java.util.*; class GFG{ static int mod = (int)(1e9 + 7); // Initializing a table in order to// store the bell trianglestatic int [][]dp; // Function to calculate the K-th// bell numberstatic 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 possiblestatic 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 codepublic 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 possiblemod = 1e9 + 7 # Initializing a table in order to# store the bell triangledp = [[-1 for x in range(6)]          for y in range(6)] # Function to calculate the K-th# bell numberdef 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 possibledef 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 codeif __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 possibleusing System; class GFG{ static int mod = (int)(1e9 + 7); // Initializing a table in order to// store the bell trianglestatic int [,]dp; // Function to calculate the K-th// bell numberstatic 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 possiblestatic 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 codepublic 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>
541
 
Amal Kumar Choubey
ukasp
umadevi9616
Dynamic Programming
Mathematical
Dynamic Programming
Mathematical
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Count All Palindrome Sub-Strings in a String | Set 1
Optimal Substructure Property in Dynamic Programming | DP-2
Maximum sum such that no two elements are adjacent
Min Cost Path | DP-6
Optimal Binary Search Tree | DP-24
Write a program to print all permutations of a given string
C++ Data Types
Set in C++ Standard Template Library (STL)
Program to find GCD or HCF of two numbers
Modulo Operator (%) in C/C++ with Examples