📜  计算N名学生的排名方法,以使相同的排名成为可能

📅  最后修改于: 2021-04-29 08:57:50             🧑  作者: Mango

给定一个代表学生人数的数字N ,任务是计算所有可能的方式,根据他们的CGPA /分数对他们进行排名,同时考虑到两个或更多学生可以具有相同的排名。由于答案可能很大,因此请使用10 9 + 7取模。

例子:

方法:这个问题的想法是使用贝尔号码。

  • 响铃号是一个数字,它计算一个集合的可能分区。因此,第N个响铃号是一组大小为N的非空子集的数量。
  • 例如,让我们考虑N = 3的集合{1、2、3}。与N = 3对应的响铃编号是5。这表示可以将给定集合划分为以下5个非空子集:
{{1}, {2}, {3}}
{{1, 2}, {3}}
{{1, 3}, {2}}
{{2, 3}, {1}}
{{1, 2, 3}}
  • 显然,上面的铃号表示所有可能的等级。但是,它们不计算子集的排列。
  • 因此,通过将每个子集乘以K!(其中K表示各个子集的大小),我们得到所有可能的排列。
  • 由于可以重复相同的子问题,因此我们可以将每个子问题的值存储在数据结构中以优化复杂性。

下面是上述方法的实现:

C++
// C++ program to calculate the number
// of ways to give ranks for N
// students such that same ranks
// are possible
 
#include 
using namespace std;
 
const int mod = 1e9 + 7;
 
// Initializing a table in order to
// store the bell triangle
vector > 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(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


输出:
541