📜  计算特殊集数

📅  最后修改于: 2021-09-17 07:36:19             🧑  作者: Mango

如果对于集合X 的每个元素,该集合不包含元素X + 1 ,则称一个有序整数集是一个特殊集。给定一个整数N ,任务是找到最大元素不大于N的特殊集合的数量。由于特殊集的数量可能非常大,请打印答案模10 9 + 7

例子:

方法:这个问题可以用动态规划解决。创建一个数组dp[][] ,其中dp[i][j]存储以j结尾的长度为i的特殊集合的数量。现在,递推关系将是:

现在可以通过将dp[i][n]factorial(i)相乘来计算大小i的总特殊集。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
  
typedef long long ll;
  
const int MAX = 2 * 1000 + 10;
const int MOD = 1e9 + 7;
  
// To store the states of the dp
ll dp[MAX][MAX];
  
// Function to return (a + b) % MOD
ll sum(ll a, ll b)
{
    return ((a % MOD) + (b % MOD)) % MOD;
}
  
// Function to return (a * b) % MOD
ll mul(ll a, ll b)
{
    return ((a % MOD) * (b % MOD)) % MOD;
}
  
// Function to return the count
// of special sets
int cntSpecialSet(int n)
{
  
    // Fill the dp[][] array with the answer
    // for the special sets of size 1
    for (int i = 1; i <= n; i++) {
        dp[1][i] = 1;
  
        // Take prefix sum of the current row which
        // will be used to fill the next row
        dp[1][i] += dp[1][i - 1];
    }
  
    // Fill the rest of the dp[][] array
    for (int i = 2; i <= n; i++) {
  
        // Recurrence relation
        for (int j = 2; j <= n; j++) {
            dp[i][j] = dp[i - 1][j - 2];
        }
  
        // Calculate the prefix sum
        for (int j = 1; j <= n; j++) {
            dp[i][j] = sum(dp[i][j], dp[i][j - 1]);
        }
    }
  
    ll ways(1), ans(0);
  
    for (int i = 1; i <= n; i++) {
  
        // To find special set of size i
        ways = mul(ways, i);
  
        // Addition of special sets of all sizes
        ans = sum(ans, mul(ways, dp[i][n]));
    }
  
    return ans;
}
  
// Driver code
int main()
{
    int n = 3;
  
    cout << cntSpecialSet(n);
  
    return 0;
}


Java
// Java implementation of the approach
import java.util.*;
  
class GFG 
{
static int MAX = 2 * 1000 + 10;
static int MOD = (int) (1e9 + 7);
  
// To store the states of the dp
static long [][]dp = new long[MAX][MAX];
  
// Function to return (a + b) % MOD
static long sum(long a, long b)
{
    return ((a % MOD) + (b % MOD)) % MOD;
}
  
// Function to return (a * b) % MOD
static long mul(long a, long b)
{
    return ((a % MOD) * (b % MOD)) % MOD;
}
  
// Function to return the count
// of special sets
static long cntSpecialSet(int n)
{
  
    // Fill the dp[][] array with the answer
    // for the special sets of size 1
    for (int i = 1; i <= n; i++) 
    {
        dp[1][i] = 1;
  
        // Take prefix sum of the current row which
        // will be used to fill the next row
        dp[1][i] += dp[1][i - 1];
    }
  
    // Fill the rest of the dp[][] array
    for (int i = 2; i <= n; i++) 
    {
  
        // Recurrence relation
        for (int j = 2; j <= n; j++) 
        {
            dp[i][j] = dp[i - 1][j - 2];
        }
  
        // Calculate the prefix sum
        for (int j = 1; j <= n; j++) 
        {
            dp[i][j] = sum(dp[i][j], dp[i][j - 1]);
        }
    }
  
    long ways = 1, ans = 0;
   
    for (int i = 1; i <= n; i++) 
    {
  
        // To find special set of size i
        ways = mul(ways, i);
  
        // Addition of special sets of all sizes
        ans = sum(ans, mul(ways, dp[i][n]));
    }
  
    return ans;
}
  
// Driver code
public static void main(String[] args)
{
    int n = 3;
  
    System.out.println(cntSpecialSet(n));
}
}
  
// This code is contributed by PrinciRaj1992


Python3
# Python3 implementation of the approach
  
# Function to print the nodes having 
# maximum and minimum degree 
def minMax(edges, leng, n) : 
  
    # Map to store the degrees of every node 
    m = {};
      
    for i in range(leng) :
        m[edges[i][0]] = 0;
        m[edges[i][1]] = 0;
          
    for i in range(leng) :
          
        # Storing the degree for each node
        m[edges[i][0]] += 1;
        m[edges[i][1]] += 1; 
  
    # maxi and mini variables to store 
    # the maximum and minimum degree 
    maxi = 0; 
    mini = n; 
  
    for i in range(1, n + 1) :
        maxi = max(maxi, m[i]); 
        mini = min(mini, m[i]); 
  
    # Printing all the nodes 
    # with maximum degree 
    print("Nodes with maximum degree : ", 
                                end = "")
      
    for i in range(1, n + 1) :
        if (m[i] == maxi) :
            print(i, end = " "); 
  
    print()
  
    # Printing all the nodes 
    # with minimum degree 
    print("Nodes with minimum degree : ", 
                                end = "")
      
    for i in range(1, n + 1) :
        if (m[i] == mini) :
            print(i, end = " "); 
  
# Driver code 
if __name__ == "__main__" : 
  
    # Count of nodes and edges 
    n = 4; m = 6; 
  
    # The edge list 
    edges = [[ 1, 2 ], [ 1, 3 ], 
             [ 1, 4 ], [ 2, 3 ], 
             [ 2, 4 ], [ 3, 4 ]]; 
  
    minMax(edges, m, 4); 
  
# This code is contributed by AnkitRai01


C#
// C# implementation of the approach
using System;
      
class GFG 
{
      
static int MAX = 2 * 1000 + 10;
static int MOD = (int) (1e9 + 7);
  
// To store the states of the dp
static long [,]dp = new long[MAX, MAX];
  
// Function to return (a + b) % MOD
static long sum(long a, long b)
{
    return ((a % MOD) + (b % MOD)) % MOD;
}
  
// Function to return (a * b) % MOD
static long mul(long a, long b)
{
    return ((a % MOD) * (b % MOD)) % MOD;
}
  
// Function to return the count
// of special sets
static long cntSpecialSet(int n)
{
  
    // Fill the dp[,] array with the answer
    // for the special sets of size 1
    for (int i = 1; i <= n; i++) 
    {
        dp[1, i] = 1;
  
        // Take prefix sum of the current row which
        // will be used to fill the next row
        dp[1, i] += dp[1, i - 1];
    }
  
    // Fill the rest of the dp[,] array
    for (int i = 2; i <= n; i++) 
    {
  
        // Recurrence relation
        for (int j = 2; j <= n; j++) 
        {
            dp[i, j] = dp[i - 1, j - 2];
        }
  
        // Calculate the prefix sum
        for (int j = 1; j <= n; j++) 
        {
            dp[i, j] = sum(dp[i, j], dp[i, j - 1]);
        } 
    }
  
    long ways = 1, ans = 0;
  
    for (int i = 1; i <= n; i++) 
    {
  
        // To find special set of size i
        ways = mul(ways, i);
  
        // Addition of special sets of all sizes
        ans = sum(ans, mul(ways, dp[i, n]));
    }
  
    return ans;
}
  
// Driver code
public static void Main(String[] args)
{
    int n = 3;
  
    Console.WriteLine(cntSpecialSet(n));
}
}
  
// This code is contributed by Princi Singh


输出:
5

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程