📌  相关文章
📜  形成具有不同相邻元素的数组的方法数量

📅  最后修改于: 2021-04-29 06:38:20             🧑  作者: Mango

给定三个整数N,M和X,任务是找到形成数组的方式的数目,以使该数组的所有连续数都不同,并且该数组的任何索引处的值都从2到N – 1(考虑基于1的索引在1和M之间,而索引1的值为X,索引N的值为1。
注意:X的值在1到M之间。

例子:

方法:可以使用动态编程解决问题。令f(i)表示直到第i个索引为止形成数组的方式的数量,这样数组的每个连续元素都是不同的。令f(i,One)表示直到第i个索引为止形成数组的方式的数量,以使数组的每个连续元素都不同并且arr i = 1。
类似地,令f(i,Non-One)表示直到第i个索引为止形成数组的方式的数目,这样数组的每个连续元素都是不同的,并且arr i不等于1。

形成以下重复发生:

f(i, Non-One) = f(i - 1, One) * (M - 1) + f(i - 1, Non-One) * (M - 2)

这意味着使用两种情况形成直到数组i的第i个索引不等于1的第i个索引的数组的形成方法的数量:

  1. 如果数组i – 1上的数字为1,则从(M – 1)选项中选择一个数字放在第i索引处,因为数组i不等于1。
  2. 如果数组i – 1处的数字不为1,则我们需要从(M – 2)个选项中选择一个数字,因为数组i不等于1并且数组i ≠数组i – 1

同样, f(i,One)= f(i – 1,Non-One) ,因为直到数组i = 1的第i个索引为止,形成数组的方法的数量与直到数组i的形成方法的数量相同数组i – 1 ≠1的第(i – 1)个索引,因此在第i索引处只有一个选择。最后,由于数组N需要等于1,因此如果f(N,One)是必需的答案。

下面是上述方法的实现:

C++
// C++ program to count the number of ways
// to form arrays of N numbers such that the
// first and last numbers are fixed
// and all consecutive numbers are distinct
#include 
using namespace std;
  
// Returns the total ways to form arrays such that
// every consecutive element is different and each
// element except the first and last can take values
// from 1 to M
int totalWays(int N, int M, int X)
{
  
    // define the dp[][] array
    int dp[N + 1][2];
  
    // if the first element is 1
    if (X == 1) {
  
        // there is only one way to place
        // a 1 at the first index
        dp[0][0] = 1;
    }
    else {
  
        // the value at first index needs to be 1,
        // thus there is no way to place a non-one integer
        dp[0][1] = 0;
    }
  
    // if the first element was 1 then at index 1,
    // only non one integer can be placed thus
    // there are M - 1 ways to place a non one integer
    // at index 2 and 0 ways to place a 1 at the 2nd index
    if (X == 1) {
        dp[1][0] = 0;
        dp[1][1] = M - 1;
    }
  
    // Else there is one way to place a one at
    // index 2 and if a non one needs to be placed here,
    // there are (M - 2) options, i.e
    // neither the element at this index
    // should be 1, neither should it be
    // equal to the previous element
    else {
        dp[1][0] = 1;
        dp[1][1] = (M - 2);
    }
  
    // Build the dp array in bottom up manner
    for (int i = 2; i < N; i++) {
  
        // f(i, one) = f(i - 1, non-one)
        dp[i][0] = dp[i - 1][1];
  
        // f(i, non-one) = f(i - 1, one) * (M - 1) +
        // f(i - 1, non-one) * (M - 2)
        dp[i][1] = dp[i - 1][0] * (M - 1) + dp[i - 1][1] * (M - 2);
    }
  
    // last element needs to be one, so return dp[n - 1][0]
    return dp[N - 1][0];
}
  
// Driver Code
int main()
{
  
    int N = 4, M = 3, X = 2;
    cout << totalWays(N, M, X) << endl;
  
    return 0;
}


Java
// Java program to count the 
// number of ways to form 
// arrays of N numbers such 
// that the first and last 
// numbers are fixed and all 
// consecutive numbers are 
// distinct
import java.io.*;
  
class GFG 
{
  
// Returns the total ways to 
// form arrays such that every 
// consecutive element is 
// different and each element 
// except the first and last 
// can take values from 1 to M
static int totalWays(int N, 
                     int M, int X)
{
  
    // define the dp[][] array
    int dp[][] = new int[N + 1][2];
  
    // if the first element is 1
    if (X == 1) 
    {
  
        // there is only one 
        // way to place a 1 
        // at the first index
        dp[0][0] = 1;
    }
    else 
    {
  
        // the value at first index 
        // needs to be 1, thus there 
        // is no way to place a 
        // non-one integer
        dp[0][1] = 0;
    }
  
    // if the first element was 1 
    // then at index 1, only non 
    // one integer can be placed 
    // thus there are M - 1 ways 
    // to place a non one integer
    // at index 2 and 0 ways to 
    // place a 1 at the 2nd index
    if (X == 1)
    {
        dp[1][0] = 0;
        dp[1][1] = M - 1;
    }
  
    // Else there is one way to 
    // place a one at index 2 
    // and if a non one needs to 
    // be placed here, there are 
    // (M - 2) options, i.e neither
    // the element at this index
    // should be 1, neither should 
    // it be equal to the previous 
    // element
    else 
    {
        dp[1][0] = 1;
        dp[1][1] = (M - 2);
    }
  
    // Build the dp array
    // in bottom up manner
    for (int i = 2; i < N; i++) 
    {
  
        // f(i, one) = f(i - 1, 
        // non-one)
        dp[i][0] = dp[i - 1][1];
  
        // f(i, non-one) = 
        // f(i - 1, one) * (M - 1) +
        // f(i - 1, non-one) * (M - 2)
        dp[i][1] = dp[i - 1][0] * (M - 1) + 
                   dp[i - 1][1] * (M - 2);
    }
  
    // last element needs to be
    // one, so return dp[n - 1][0]
    return dp[N - 1][0];
}
  
// Driver Code
public static void main (String[] args)
{
    int N = 4, M = 3, X = 2;
    System.out.println(totalWays(N, M, X));
}
}
  
// This code is contributed by anuj_67.


Python3
# Python 3 program to count the number of ways
# to form arrays of N numbers such that the
# first and last numbers are fixed
# and all consecutive numbers are distinct
  
# Returns the total ways to form arrays such that
# every consecutive element is different and each
# element except the first and last can take values
# from 1 to M
def totalWays(N,M,X):
      
    # define the dp[][] array
    dp = [[0 for i in range(2)] for j in range(N+1)]
  
    # if the first element is 1
    if (X == 1):
          
        # there is only one way to place
        # a 1 at the first index
        dp[0][0] = 1
  
    else:
        # the value at first index needs to be 1,
        # thus there is no way to place a non-one integer
        dp[0][1] = 0
  
    # if the first element was 1 then at index 1,
    # only non one integer can be placed thus
    # there are M - 1 ways to place a non one integer
    # at index 2 and 0 ways to place a 1 at the 2nd index
    if (X == 1):
        dp[1][0] = 0
        dp[1][1] = M - 1
  
    # Else there is one way to place a one at
    # index 2 and if a non one needs to be placed here,
    # there are (M - 2) options, i.e
    # neither the element at this index
    # should be 1, neither should it be
    # equal to the previous element
    else:
        dp[1][0] = 1
        dp[1][1] = (M - 2)
  
    # Build the dp array in bottom up manner
    for i in range(2,N):
        # f(i, one) = f(i - 1, non-one)
        dp[i][0] = dp[i - 1][1]
  
        # f(i, non-one) = f(i - 1, one) * (M - 1) +
        # f(i - 1, non-one) * (M - 2)
        dp[i][1] = dp[i - 1][0] * (M - 1) + dp[i - 1][1] * (M - 2)
  
    # last element needs to be one, so return dp[n - 1][0]
    return dp[N - 1][0]
  
# Driver Code
if __name__ == '__main__':
    N = 4
    M = 3
    X = 2
    print(totalWays(N, M, X))
      
# This code is contributed by
# Surendra_Gangwar


C#
// C# program to count the 
// number of ways to form 
// arrays of N numbers such 
// that the first and last 
// numbers are fixed and all 
// consecutive numbers are 
// distinct
using System;
  
class GFG 
{
  
// Returns the total ways to 
// form arrays such that every 
// consecutive element is 
// different and each element 
// except the first and last 
// can take values from 1 to M
static int totalWays(int N, 
                     int M, int X)
{
  
    // define the dp[][] array
    int [,]dp = new int[N + 1, 2];
  
    // if the first element is 1
    if (X == 1) 
    {
  
        // there is only one 
        // way to place a 1 
        // at the first index
        dp[0, 0] = 1;
    }
    else
    {
  
        // the value at first index 
        // needs to be 1, thus there 
        // is no way to place a 
        // non-one integer
        dp[0, 1] = 0;
    }
  
    // if the first element was 1 
    // then at index 1, only non 
    // one integer can be placed 
    // thus there are M - 1 ways 
    // to place a non one integer
    // at index 2 and 0 ways to 
    // place a 1 at the 2nd index
    if (X == 1)
    {
        dp[1, 0] = 0;
        dp[1, 1] = M - 1;
    }
  
    // Else there is one way to 
    // place a one at index 2 
    // and if a non one needs to 
    // be placed here, there are 
    // (M - 2) options, i.e neither
    // the element at this index
    // should be 1, neither should 
    // it be equal to the previous 
    // element
    else
    {
        dp[1, 0] = 1;
        dp[1, 1] = (M - 2);
    }
  
    // Build the dp array
    // in bottom up manner
    for (int i = 2; i < N; i++) 
    {
  
        // f(i, one) = f(i - 1, 
        // non-one)
        dp[i, 0] = dp[i - 1, 1];
  
        // f(i, non-one) = 
        // f(i - 1, one) * (M - 1) +
        // f(i - 1, non-one) * (M - 2)
        dp[i, 1] = dp[i - 1, 0] * (M - 1) + 
                   dp[i - 1, 1] * (M - 2);
    }
  
    // last element needs to be
    // one, so return dp[n - 1][0]
    return dp[N - 1, 0];
}
  
// Driver Code
public static void Main ()
{
    int N = 4, M = 3, X = 2;
    Console.WriteLine(totalWays(N, M, X));
}
}
  
// This code is contributed
// by anuj_67.


PHP


输出:
3

时间复杂度: O(N),其中N是数组的大小