📜  计算排列前N个号码的方式的数量

📅  最后修改于: 2021-05-04 18:16:08             🧑  作者: Mango

计算在行中排列前N个自然数的方式的数目,以使最左边的数字始终为1,并且没有两个连续的数的绝对差大于2
例子:

天真的方法:生成所有排列并计算其中有多少满足给定条件。
下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
 
// Function to return the count
// of required arrangements
int countWays(int n)
{
 
    // Create a vector
    vector a;
    int i = 1;
 
    // Store numbers from 1 to n
    while (i <= n)
        a.push_back(i++);
 
    // To store the count of ways
    int ways = 0;
 
    // Generate all the permutations
    // using next_permutation in STL
    do {
        // Initialize flag to true if first
        // element is 1 else false
        bool flag = (a[0] == 1);
 
        // Checking if the current permutation
        // satisfies the given conditions
        for (int i = 1; i < n; i++) {
 
            // If the current permutation is invalid
            // then set the flag to false
            if (abs(a[i] - a[i - 1]) > 2)
                flag = 0;
        }
 
        // If valid arrangement
        if (flag)
            ways++;
 
        // Generate the next permutation
    } while (next_permutation(a.begin(), a.end()));
 
    return ways;
}
 
// Driver code
int main()
{
    int n = 6;
 
    cout << countWays(n);
 
    return 0;
}


Java
// Java implementation of the
// above approach
import java.util.*;
class GFG{
 
// Function to return the count
// of required arrangements
static int countWays(int n)
{
  // Create a vector
  Vector a =
         new Vector<>();
  int i = 1;
 
  // Store numbers from
  // 1 to n
  while (i <= n)
    a.add(i++);
 
  // To store the count
  // of ways
  int ways = 0;
 
  // Generate all the permutations
  // using next_permutation in STL
  do
  {
    // Initialize flag to true
    // if first element is 1
    // else false
    boolean flag = (a.get(0) == 1);
 
    // Checking if the current
    // permutation satisfies the
    // given conditions
    for (int j = 1; j < n; j++)
    {
      // If the current permutation
      // is invalid then set the
      // flag to false
      if (Math.abs(a.get(j) -
                   a.get(j - 1)) > 2)
        flag = false;
    }
 
    // If valid arrangement
    if (flag)
      ways++;
 
    // Generate the next permutation
  } while (next_permutation(a));
 
  return ways;
}
   
static boolean next_permutation(Vector p)
{
  for (int a = p.size() - 2;
           a >= 0; --a)
    if (p.get(a) < p.get(a + 1))
      for (int b = p.size() - 1;; --b)
        if (p.get(b) > p.get(a))
        {
          int t = p.get(a);
          p.set(a, p.get(b));
          p.set(b, t);
 
          for (++a, b = p.size() - 1;
                 a < b; ++a, --b)
          {
            t = p.get(a);
            p.set(a, p.get(b));
            p.set(b, t);
          }
          return true;
        }
  return false;
}
 
// Driver code
public static void main(String[] args)
{
  int n = 6;
  System.out.print(countWays(n));
}
}
 
// This code is contributed by shikhasingrajput


C#
// C# implementation of the
// above approach
using System;
using System.Collections.Generic;
class GFG{
 
// Function to return the count
// of required arrangements
static int countWays(int n)
{
  // Create a vector
  List a =
       new List();
  int i = 1;
 
  // Store numbers from
  // 1 to n
  while (i <= n)
    a.Add(i++);
 
  // To store the count
  // of ways
  int ways = 0;
 
  // Generate all the
  // permutations using
  // next_permutation in STL
  do
  {
    // Initialize flag to true
    // if first element is 1
    // else false
    bool flag = (a[0] == 1);
 
    // Checking if the current
    // permutation satisfies the
    // given conditions
    for (int j = 1; j < n; j++)
    {
      // If the current permutation
      // is invalid then set the
      // flag to false
      if (Math.Abs(a[j] -
                   a[j - 1]) > 2)
        flag = false;
    }
 
    // If valid arrangement
    if (flag)
      ways++;
 
    // Generate the next
    // permutation
  } while (next_permutation(a));
 
  return ways;
}
   
static bool next_permutation(List p)
{
  for (int a = p.Count - 2;
           a >= 0; --a)
    if (p[a] < p[a + 1])
      for (int b = p.Count - 1;; --b)
        if (p[b] > p[a])
        {
          int t = p[a];
          p[a] = p[b];
          p[b]  =  t;
 
          for (++a, b = p.Count - 1;
                 a < b; ++a, --b)
          {
            t = p[a];
            p[a] = p[b];
            p[b] = t;
          }
          return true;
        }
  return false;
}
 
// Driver code
public static void Main(String[] args)
{
  int n = 6;
  Console.Write(countWays(n));
}
}
 
// This code is contributed by Rajput-Ji


C++
// C++ implementation of the approach
#include 
using namespace std;
 
// Function to return the count
// of required arrangements
int countWays(int n)
{
    // Create the dp array
    int dp[n + 1];
 
    // Initialize the base cases
    // as explained above
    dp[0] = 0;
    dp[1] = 1;
 
    // (12) as the only possibility
    dp[2] = 1;
 
    // Generate answer for greater values
    for (int i = 3; i <= n; i++) {
        dp[i] = dp[i - 1] + dp[i - 3] + 1;
    }
 
    // dp[n] contains the desired answer
    return dp[n];
}
 
// Driver code
int main()
{
    int n = 6;
 
    cout << countWays(n);
 
    return 0;
}


Java
// Java implementation of the approach
class GFG
{
 
// Function to return the count
// of required arrangements
static int countWays(int n)
{
    // Create the dp array
    int []dp = new int[n + 1];
 
    // Initialize the base cases
    // as explained above
    dp[0] = 0;
    dp[1] = 1;
 
    // (12) as the only possibility
    dp[2] = 1;
 
    // Generate answer for greater values
    for (int i = 3; i <= n; i++)
    {
        dp[i] = dp[i - 1] + dp[i - 3] + 1;
    }
 
    // dp[n] contains the desired answer
    return dp[n];
}
 
// Driver code
public static void main(String args[])
{
    int n = 6;
    System.out.println(countWays(n));
}
}
 
// This code is contributed by 29AjayKumar


Python3
# Python implementation of the approach
 
# Function to return the count
# of required arrangements
def countWays(n):
     
    # Create the dp array
    dp = [0 for i in range(n + 1)]
 
    # Initialize the base cases
    # as explained above
    dp[0] = 0
    dp[1] = 1
 
    # (12) as the only possibility
    dp[2] = 1
 
    # Generate answer for greater values
    for i in range(3, n + 1):
        dp[i] = dp[i - 1] + dp[i - 3] + 1
 
    # dp[n] contains the desired answer
    return dp[n]
 
# Driver code
n = 6
 
print(countWays(n))
 
# This code is contributed by Mohit Kumar


C#
// C# implementation of the approach
using System;
class GFG
{
 
// Function to return the count
// of required arrangements
static int countWays(int n)
{
    // Create the dp array
    int []dp = new int[n + 1];
 
    // Initialize the base cases
    // as explained above
    dp[0] = 0;
    dp[1] = 1;
 
    // (12) as the only possibility
    dp[2] = 1;
 
    // Generate answer for greater values
    for (int i = 3; i <= n; i++)
    {
        dp[i] = dp[i - 1] + dp[i - 3] + 1;
    }
 
    // dp[n] contains the desired answer
    return dp[n];
}
 
// Driver code
public static void Main()
{
    int n = 6;
    Console.WriteLine(countWays(n));
}
}
 
// This code is contributed by Code@Mech.


输出:
9






高效方法:可以使用动态编程解决此问题。
解决此问题的更好的线性方法取决于以下观察。寻找2的位置。令a [i]为n = i的路数。有以下三种情况:

  1. 12_____ –第二个位置为“ 2”。
  2. 1 * 2 ____ –“ 2”在第三位置。
    1 ** 2 ___ –不可能在第四位置显示“ 2”,因为唯一可能的方式是(1342),与情况3相同。
    1 *** 2__ – “2”中的第五位置是不可能的,因为1必须后跟3,3×52需要4之前,这样它变得13542,再次作为壳体3。
  3. 1_(i – 2)项___2 –最后位置的“ 2”(1357642及类似位置)

对于每种情况,以下是子任务:
将a [i – 1]的每个项加1,即(1 __(i – 1)个项__)。
至于1_2_____,只能有一个1324 ___(i – 4)个项____,即a [i – 3]。
因此,递归关系将是

基本情况将是:

下面是上述方法的实现:

C++

// C++ implementation of the approach
#include 
using namespace std;
 
// Function to return the count
// of required arrangements
int countWays(int n)
{
    // Create the dp array
    int dp[n + 1];
 
    // Initialize the base cases
    // as explained above
    dp[0] = 0;
    dp[1] = 1;
 
    // (12) as the only possibility
    dp[2] = 1;
 
    // Generate answer for greater values
    for (int i = 3; i <= n; i++) {
        dp[i] = dp[i - 1] + dp[i - 3] + 1;
    }
 
    // dp[n] contains the desired answer
    return dp[n];
}
 
// Driver code
int main()
{
    int n = 6;
 
    cout << countWays(n);
 
    return 0;
}

Java

// Java implementation of the approach
class GFG
{
 
// Function to return the count
// of required arrangements
static int countWays(int n)
{
    // Create the dp array
    int []dp = new int[n + 1];
 
    // Initialize the base cases
    // as explained above
    dp[0] = 0;
    dp[1] = 1;
 
    // (12) as the only possibility
    dp[2] = 1;
 
    // Generate answer for greater values
    for (int i = 3; i <= n; i++)
    {
        dp[i] = dp[i - 1] + dp[i - 3] + 1;
    }
 
    // dp[n] contains the desired answer
    return dp[n];
}
 
// Driver code
public static void main(String args[])
{
    int n = 6;
    System.out.println(countWays(n));
}
}
 
// This code is contributed by 29AjayKumar

Python3

# Python implementation of the approach
 
# Function to return the count
# of required arrangements
def countWays(n):
     
    # Create the dp array
    dp = [0 for i in range(n + 1)]
 
    # Initialize the base cases
    # as explained above
    dp[0] = 0
    dp[1] = 1
 
    # (12) as the only possibility
    dp[2] = 1
 
    # Generate answer for greater values
    for i in range(3, n + 1):
        dp[i] = dp[i - 1] + dp[i - 3] + 1
 
    # dp[n] contains the desired answer
    return dp[n]
 
# Driver code
n = 6
 
print(countWays(n))
 
# This code is contributed by Mohit Kumar

C#

// C# implementation of the approach
using System;
class GFG
{
 
// Function to return the count
// of required arrangements
static int countWays(int n)
{
    // Create the dp array
    int []dp = new int[n + 1];
 
    // Initialize the base cases
    // as explained above
    dp[0] = 0;
    dp[1] = 1;
 
    // (12) as the only possibility
    dp[2] = 1;
 
    // Generate answer for greater values
    for (int i = 3; i <= n; i++)
    {
        dp[i] = dp[i - 1] + dp[i - 3] + 1;
    }
 
    // dp[n] contains the desired answer
    return dp[n];
}
 
// Driver code
public static void Main()
{
    int n = 6;
    Console.WriteLine(countWays(n));
}
}
 
// This code is contributed by Code@Mech.
输出:
9