📜  计算不包含连续数字的有序集合的数量

📅  最后修改于: 2021-05-04 17:17:23             🧑  作者: Mango

给定正整数N。计算任意大小的有序集合的总数,以使该集合中不存在连续的数字,并且所有数字均<=N。

例子:

天真的方法:

  • 我们将使用递归来解决此问题。如果我们得到有序集的C值,其中元素按升/降序排列,并且集合大小为S,则该大小的总计数将为

C * S!

  • 我们将对每个不同大小的有序集合执行此操作。
  • 迭代所有有序集的大小,并为每种大小找到有序集的计数,然后乘以大小的阶乘(S!)。在每个递归步骤中,我们都有两个选择–
    1. 包含当前元素x并移动到下一个位置,其中最大元素现在可以作为x – 2包含在内。
    2. 不要包含当前元素x,而将当前元素包含在当前位置,此时可以包含的最大元素为x – 1。
  • 因此,递归关系为:
countSets(x, pos) = countSets(x-2, pos-1) + countSets(x-1, pos)

C++
// C++ program to Count the number of
// ordered sets not containing
// consecutive numbers
#include 
using namespace std;
 
// Function to calculate the count
// of ordered set for a given size
int CountSets(int x, int pos)
{
    // Base cases
    if (x <= 0) {
        if (pos == 0)
            return 1;
        else
            return 0;
    }
    if (pos == 0)
        return 1;
 
    int answer = CountSets(x - 1, pos)
              + CountSets(x - 2, pos - 1);
     
    return answer;
}
// Function returns the count
// of all ordered sets
int CountOrderedSets(int n)
{
    // Prestore the factorial value
    int factorial[10000];
    factorial[0] = 1;
 
    for (int i = 1; i < 10000; i++)
        factorial[i] = factorial[i - 1] * i;
 
    int answer = 0;
 
    // Iterate all ordered set sizes and find
    // the count for each one maximum ordered
    // set size will be smaller than N as all
    // elements are distinct and non consecutive
    for (int i = 1; i <= n; i++) {
 
        // Multiply ny size! for all the
        // arrangements because sets are ordered
        int sets = CountSets(n, i) * factorial[i];
         
        // Add to total answer
        answer = answer + sets;
    }
    return answer;
}
// Driver code
int main()
{
    int N = 3;
 
    cout << CountOrderedSets(N);
 
    return 0;
}


Java
// Java program to count the number 
// of ordered sets not containing
// consecutive numbers
class GFG{
 
// Function to calculate the count
// of ordered set for a given size
static int CountSets(int x, int pos)
{
     
    // Base cases
    if (x <= 0)
    {
        if (pos == 0)
            return 1;
        else
            return 0;
    }
    if (pos == 0)
        return 1;
 
    int answer = CountSets(x - 1, pos) +
                 CountSets(x - 2, pos - 1);
    return answer;
}
 
// Function returns the count
// of all ordered sets
static int CountOrderedSets(int n)
{
     
    // Prestore the factorial value
    int []factorial = new int[10000];
    factorial[0] = 1;
 
    for(int i = 1; i < 10000; i++)
       factorial[i] = factorial[i - 1] * i;
 
    int answer = 0;
 
    // Iterate all ordered set sizes and find
    // the count for each one maximum ordered
    // set size will be smaller than N as all
    // elements are distinct and non consecutive
    for(int i = 1; i <= n; i++)
    {
        
       // Multiply ny size! for all the
       // arrangements because sets are ordered
       int sets = CountSets(n, i) * factorial[i];
        
       // Add to total answer
       answer = answer + sets;
    }
    return answer;
}
 
// Driver code
public static void main(String[] args)
{
    int N = 3;
 
    System.out.print(CountOrderedSets(N));
}
}
 
// This code is contributed by sapnasingh4991


Python3
# Python3 program to count the number of
# ordered sets not containing
# consecutive numbers
 
# Function to calculate the count
# of ordered set for a given size
def CountSets(x, pos):
     
    # Base cases
    if (x <= 0):
        if (pos == 0):
            return 1
        else:
            return 0
    if (pos == 0):
        return 1
 
    answer = (CountSets(x - 1, pos) +
              CountSets(x - 2, pos - 1))
               
    return answer
     
# Function returns the count
# of all ordered sets
def CountOrderedSets(n):
     
    # Prestore the factorial value
    factorial = [1 for i in range(10000)]
    factorial[0] = 1
 
    for i in range(1, 10000, 1):
        factorial[i] = factorial[i - 1] * i
 
    answer = 0
 
    # Iterate all ordered set sizes and find
    # the count for each one maximum ordered
    # set size will be smaller than N as all
    # elements are distinct and non consecutive
    for i in range(1, n + 1, 1):
         
        # Multiply ny size! for all the
        # arrangements because sets are ordered
        sets = CountSets(n, i) * factorial[i]
         
        # Add to total answer
        answer = answer + sets
         
    return answer
 
# Driver code
if __name__ == '__main__':
     
    N = 3
    print(CountOrderedSets(N))
 
# This code is contributed by Samarth


C#
// C# program to count the number
// of ordered sets not containing
// consecutive numbers
using System;
class GFG{
 
// Function to calculate the count
// of ordered set for a given size
static int CountSets(int x, int pos)
{
     
    // Base cases
    if (x <= 0)
    {
        if (pos == 0)
            return 1;
        else
            return 0;
    }
    if (pos == 0)
        return 1;
 
    int answer = CountSets(x - 1, pos) +
                 CountSets(x - 2, pos - 1);
    return answer;
}
 
// Function returns the count
// of all ordered sets
static int CountOrderedSets(int n)
{
     
    // Prestore the factorial value
    int []factorial = new int[10000];
    factorial[0] = 1;
 
    for(int i = 1; i < 10000; i++)
    factorial[i] = factorial[i - 1] * i;
 
    int answer = 0;
 
    // Iterate all ordered set sizes and find
    // the count for each one maximum ordered
    // set size will be smaller than N as all
    // elements are distinct and non consecutive
    for(int i = 1; i <= n; i++)
    {
         
        // Multiply ny size! for all the
        // arrangements because sets are ordered
        int sets = CountSets(n, i) * factorial[i];
             
        // Add to total answer
        answer = answer + sets;
    }
    return answer;
}
 
// Driver code
public static void Main(String[] args)
{
    int N = 3;
 
    Console.Write(CountOrderedSets(N));
}
}
 
// This code is contributed by sapnasingh4991


C++
// C++ program to Count the number
// of ordered sets not containing
// consecutive numbers
#include 
using namespace std;
 
// DP table
int dp[500][500];
 
// Function to calculate the count
// of ordered set for a given size
int CountSets(int x, int pos)
{
    // Base cases
    if (x <= 0) {
        if (pos == 0)
            return 1;
        else
            return 0;
    }
    if (pos == 0)
        return 1;
 
    // If subproblem has been
    // soved before
    if (dp[x][pos] != -1)
        return dp[x][pos];
 
    int answer = CountSets(x - 1, pos)
        + CountSets(x - 2, pos - 1);
 
    // Store and return answer to
    // this subproblem
    return dp[x][pos] = answer;
}
 
// Function returns the count
// of all ordered sets
int CountOrderedSets(int n)
{
    // Prestore the factorial value
    int factorial[10000];
    factorial[0] = 1;
 
    for (int i = 1; i < 10000; i++)
        factorial[i] = factorial[i - 1] * i;
 
    int answer = 0;
 
    // Initialise the dp table
    memset(dp, -1, sizeof(dp));
 
    // Iterate all ordered set sizes and find
    // the count for each one maximum ordered
    // set size will be smaller than N as all
    // elements are distinct and non consecutive.
    for (int i = 1; i <= n; i++) {
 
        // Multiply ny size! for all the
        // arrangements because sets
        // are ordered.
        int sets = CountSets(n, i) * factorial[i];
         
        // Add to total answer
        answer = answer + sets;
    }
    return answer;
}
// Driver code
int main()
{
    int N = 3;
 
    cout << CountOrderedSets(N);
 
    return 0;
}


Java
// Java program to count the number
// of ordered sets not containing
// consecutive numbers
import java.util.*;
 
class GFG{
 
// DP table
static int [][]dp = new int[500][500];
 
// Function to calculate the count
// of ordered set for a given size
static int CountSets(int x, int pos)
{
     
    // Base cases
    if (x <= 0)
    {
        if (pos == 0)
            return 1;
        else
            return 0;
    }
    if (pos == 0)
        return 1;
 
    // If subproblem has been
    // soved before
    if (dp[x][pos] != -1)
        return dp[x][pos];
 
    int answer = CountSets(x - 1, pos) +
                 CountSets(x - 2, pos - 1);
 
    // Store and return answer to
    // this subproblem
    return dp[x][pos] = answer;
}
 
// Function returns the count
// of all ordered sets
static int CountOrderedSets(int n)
{
     
    // Prestore the factorial value
    int []factorial = new int[10000];
    factorial[0] = 1;
 
    for(int i = 1; i < 10000; i++)
        factorial[i] = factorial[i - 1] * i;
 
    int answer = 0;
 
    // Initialise the dp table
    for(int i = 0; i < 500; i++)
    {
        for(int j = 0; j < 500; j++)
        {
            dp[i][j] = -1;
        }
    }
 
    // Iterate all ordered set sizes and find
    // the count for each one maximum ordered
    // set size will be smaller than N as all
    // elements are distinct and non consecutive.
    for(int i = 1; i <= n; i++)
    {
 
        // Multiply ny size! for all the
        // arrangements because sets
        // are ordered.
        int sets = CountSets(n, i) * factorial[i];
         
        // Add to total answer
        answer = answer + sets;
    }
    return answer;
}
 
// Driver code
public static void main(String[] args)
{
    int N = 3;
 
    System.out.print(CountOrderedSets(N));
}
}
 
// This code is contributed by Rajput-Ji


Python3
# Python3 program to count the number
# of ordered sets not containing
# consecutive numbers
 
# DP table
dp = [[-1 for j in range(500)]
          for i in range(500)]
  
# Function to calculate the count
# of ordered set for a given size
def CountSets(x, pos):
 
    # Base cases
    if (x <= 0):
        if (pos == 0):
            return 1
        else:
            return 0
     
    if (pos == 0):
        return 1
  
    # If subproblem has been
    # soved before
    if (dp[x][pos] != -1):
        return dp[x][pos]
  
    answer = (CountSets(x - 1, pos) +
              CountSets(x - 2, pos - 1))
  
    # Store and return answer to
    # this subproblem
    dp[x][pos] = answer
     
    return answer
 
# Function returns the count
# of all ordered sets
def CountOrderedSets(n):
 
    # Prestore the factorial value
    factorial = [0 for i in range(10000)]
    factorial[0] = 1
     
    for i in range(1, 10000):
        factorial[i] = factorial[i - 1] * i
  
    answer = 0
  
    # Iterate all ordered set sizes and find
    # the count for each one maximum ordered
    # set size will be smaller than N as all
    # elements are distinct and non consecutive.
    for i in range(1, n + 1):
  
        # Multiply ny size! for all the
        # arrangements because sets
        # are ordered.
        sets = CountSets(n, i) * factorial[i]
          
        # Add to total answer
        answer = answer + sets
     
    return answer
 
# Driver code
if __name__=="__main__":
     
    N = 3
  
    print(CountOrderedSets(N))
 
# This code is contributed by rutvik_56


C#
// C# program to count the number
// of ordered sets not containing
// consecutive numbers
using System;
class GFG{
 
// DP table
static int [,]dp = new int[500, 500];
 
// Function to calculate the count
// of ordered set for a given size
static int CountSets(int x, int pos)
{
     
    // Base cases
    if (x <= 0)
    {
        if (pos == 0)
            return 1;
        else
            return 0;
    }
    if (pos == 0)
        return 1;
 
    // If subproblem has been
    // soved before
    if (dp[x,pos] != -1)
        return dp[x, pos];
 
    int answer = CountSets(x - 1, pos) +
                 CountSets(x - 2, pos - 1);
 
    // Store and return answer to
    // this subproblem
    return dp[x, pos] = answer;
}
 
// Function returns the count
// of all ordered sets
static int CountOrderedSets(int n)
{
     
    // Prestore the factorial value
    int []factorial = new int[10000];
    factorial[0] = 1;
 
    for(int i = 1; i < 10000; i++)
        factorial[i] = factorial[i - 1] * i;
 
    int answer = 0;
 
    // Initialise the dp table
    for(int i = 0; i < 500; i++)
    {
        for(int j = 0; j < 500; j++)
        {
            dp[i, j] = -1;
        }
    }
 
    // Iterate all ordered set sizes and find
    // the count for each one maximum ordered
    // set size will be smaller than N as all
    // elements are distinct and non consecutive.
    for(int i = 1; i <= n; i++)
    {
 
        // Multiply ny size! for all the
        // arrangements because sets
        // are ordered.
        int sets = CountSets(n, i) * factorial[i];
         
        // Add to total answer
        answer = answer + sets;
    }
    return answer;
}
 
// Driver code
public static void Main(String[] args)
{
    int N = 3;
 
    Console.Write(CountOrderedSets(N));
}
}
 
// This code is contributed by sapnasingh4991


输出:
5




时间复杂度: O(2 N )

高效方法:

  • 在递归方法中,我们要多次解决子问题,即它遵循动态编程中的Overlapping Subproblems属性。因此,我们可以使用存储表或缓存来提高解决方案的效率。

C++

// C++ program to Count the number
// of ordered sets not containing
// consecutive numbers
#include 
using namespace std;
 
// DP table
int dp[500][500];
 
// Function to calculate the count
// of ordered set for a given size
int CountSets(int x, int pos)
{
    // Base cases
    if (x <= 0) {
        if (pos == 0)
            return 1;
        else
            return 0;
    }
    if (pos == 0)
        return 1;
 
    // If subproblem has been
    // soved before
    if (dp[x][pos] != -1)
        return dp[x][pos];
 
    int answer = CountSets(x - 1, pos)
        + CountSets(x - 2, pos - 1);
 
    // Store and return answer to
    // this subproblem
    return dp[x][pos] = answer;
}
 
// Function returns the count
// of all ordered sets
int CountOrderedSets(int n)
{
    // Prestore the factorial value
    int factorial[10000];
    factorial[0] = 1;
 
    for (int i = 1; i < 10000; i++)
        factorial[i] = factorial[i - 1] * i;
 
    int answer = 0;
 
    // Initialise the dp table
    memset(dp, -1, sizeof(dp));
 
    // Iterate all ordered set sizes and find
    // the count for each one maximum ordered
    // set size will be smaller than N as all
    // elements are distinct and non consecutive.
    for (int i = 1; i <= n; i++) {
 
        // Multiply ny size! for all the
        // arrangements because sets
        // are ordered.
        int sets = CountSets(n, i) * factorial[i];
         
        // Add to total answer
        answer = answer + sets;
    }
    return answer;
}
// Driver code
int main()
{
    int N = 3;
 
    cout << CountOrderedSets(N);
 
    return 0;
}

Java

// Java program to count the number
// of ordered sets not containing
// consecutive numbers
import java.util.*;
 
class GFG{
 
// DP table
static int [][]dp = new int[500][500];
 
// Function to calculate the count
// of ordered set for a given size
static int CountSets(int x, int pos)
{
     
    // Base cases
    if (x <= 0)
    {
        if (pos == 0)
            return 1;
        else
            return 0;
    }
    if (pos == 0)
        return 1;
 
    // If subproblem has been
    // soved before
    if (dp[x][pos] != -1)
        return dp[x][pos];
 
    int answer = CountSets(x - 1, pos) +
                 CountSets(x - 2, pos - 1);
 
    // Store and return answer to
    // this subproblem
    return dp[x][pos] = answer;
}
 
// Function returns the count
// of all ordered sets
static int CountOrderedSets(int n)
{
     
    // Prestore the factorial value
    int []factorial = new int[10000];
    factorial[0] = 1;
 
    for(int i = 1; i < 10000; i++)
        factorial[i] = factorial[i - 1] * i;
 
    int answer = 0;
 
    // Initialise the dp table
    for(int i = 0; i < 500; i++)
    {
        for(int j = 0; j < 500; j++)
        {
            dp[i][j] = -1;
        }
    }
 
    // Iterate all ordered set sizes and find
    // the count for each one maximum ordered
    // set size will be smaller than N as all
    // elements are distinct and non consecutive.
    for(int i = 1; i <= n; i++)
    {
 
        // Multiply ny size! for all the
        // arrangements because sets
        // are ordered.
        int sets = CountSets(n, i) * factorial[i];
         
        // Add to total answer
        answer = answer + sets;
    }
    return answer;
}
 
// Driver code
public static void main(String[] args)
{
    int N = 3;
 
    System.out.print(CountOrderedSets(N));
}
}
 
// This code is contributed by Rajput-Ji

Python3

# Python3 program to count the number
# of ordered sets not containing
# consecutive numbers
 
# DP table
dp = [[-1 for j in range(500)]
          for i in range(500)]
  
# Function to calculate the count
# of ordered set for a given size
def CountSets(x, pos):
 
    # Base cases
    if (x <= 0):
        if (pos == 0):
            return 1
        else:
            return 0
     
    if (pos == 0):
        return 1
  
    # If subproblem has been
    # soved before
    if (dp[x][pos] != -1):
        return dp[x][pos]
  
    answer = (CountSets(x - 1, pos) +
              CountSets(x - 2, pos - 1))
  
    # Store and return answer to
    # this subproblem
    dp[x][pos] = answer
     
    return answer
 
# Function returns the count
# of all ordered sets
def CountOrderedSets(n):
 
    # Prestore the factorial value
    factorial = [0 for i in range(10000)]
    factorial[0] = 1
     
    for i in range(1, 10000):
        factorial[i] = factorial[i - 1] * i
  
    answer = 0
  
    # Iterate all ordered set sizes and find
    # the count for each one maximum ordered
    # set size will be smaller than N as all
    # elements are distinct and non consecutive.
    for i in range(1, n + 1):
  
        # Multiply ny size! for all the
        # arrangements because sets
        # are ordered.
        sets = CountSets(n, i) * factorial[i]
          
        # Add to total answer
        answer = answer + sets
     
    return answer
 
# Driver code
if __name__=="__main__":
     
    N = 3
  
    print(CountOrderedSets(N))
 
# This code is contributed by rutvik_56

C#

// C# program to count the number
// of ordered sets not containing
// consecutive numbers
using System;
class GFG{
 
// DP table
static int [,]dp = new int[500, 500];
 
// Function to calculate the count
// of ordered set for a given size
static int CountSets(int x, int pos)
{
     
    // Base cases
    if (x <= 0)
    {
        if (pos == 0)
            return 1;
        else
            return 0;
    }
    if (pos == 0)
        return 1;
 
    // If subproblem has been
    // soved before
    if (dp[x,pos] != -1)
        return dp[x, pos];
 
    int answer = CountSets(x - 1, pos) +
                 CountSets(x - 2, pos - 1);
 
    // Store and return answer to
    // this subproblem
    return dp[x, pos] = answer;
}
 
// Function returns the count
// of all ordered sets
static int CountOrderedSets(int n)
{
     
    // Prestore the factorial value
    int []factorial = new int[10000];
    factorial[0] = 1;
 
    for(int i = 1; i < 10000; i++)
        factorial[i] = factorial[i - 1] * i;
 
    int answer = 0;
 
    // Initialise the dp table
    for(int i = 0; i < 500; i++)
    {
        for(int j = 0; j < 500; j++)
        {
            dp[i, j] = -1;
        }
    }
 
    // Iterate all ordered set sizes and find
    // the count for each one maximum ordered
    // set size will be smaller than N as all
    // elements are distinct and non consecutive.
    for(int i = 1; i <= n; i++)
    {
 
        // Multiply ny size! for all the
        // arrangements because sets
        // are ordered.
        int sets = CountSets(n, i) * factorial[i];
         
        // Add to total answer
        answer = answer + sets;
    }
    return answer;
}
 
// Driver code
public static void Main(String[] args)
{
    int N = 3;
 
    Console.Write(CountOrderedSets(N));
}
}
 
// This code is contributed by sapnasingh4991
输出:
5




时间复杂度: O(N 2 )