Recuento de arrays válidas de tamaño P con elementos en el rango [1, N] que tienen duplicados separados por una distancia mínima de M

Ir a la copia de CDN Dados tres números enteros N, M y P , la tarea es encontrar el número total de arrays válidas que se pueden crear de tamaño P con cada elemento en el rango [1, N], de modo que los duplicados aparezcan al menos M distancia aparte.

Ejemplo :

Entrada: N = 2, M = 0, P = 3
Salida: 6
Explicación : Todas las arrays válidas son: {1, 2, 1}, {1, 1, 2}, {2, 1, 1}, {2, 2, 1}, {2, 1, 2}, {1, 2, 2}.

Entrada: N = 2, M = 1, P = 4
Salida: 2
Explicación : todas las arrays válidas son: {1, 2, 1, 2}, {2, 1, 2, 1}

 

Enfoque: el problema se puede resolver con la ayuda de la programación dinámica ,  

  • Hay dos opciones posibles en cada índice: o agregamos el elemento ya utilizado a una distancia de al menos M , o agregamos un nuevo elemento y disminuimos el recuento de caracteres no utilizados.
  • Para manejar esto, use programación dinámica recursiva .
  • Para acelerar las llamadas recursivas, use la memorización para que los estados ya calculados no se vuelvan a calcular.
  • Definamos:   dp[i][j][k] como el número de arreglos hasta la i-ésima posición en la que están presentes j elementos únicos yk el número de elementos que no se utilizan.
  • En cada paso hay dos opciones:
    1. Elija los elementos ocurridos previamente, j y k no cambiarían ya que el número de elementos usados ​​y no usados ​​no cambia:  dp[i+1][j][k]
    2. Elija el elemento que nunca se ha utilizado, para este caso, el número de caracteres utilizados aumentará en 1 y el número de caracteres no utilizados disminuirá en 1: dp[i+1][j+1][k-1]

dp[i][j][k] será la suma de los dos pasos anteriores, representados como: 

  •  

   dp[i][j][k] = dp[i+1][j][k] + dp[i+1][j+1][k-1]

  • La respuesta final será dp[0][0][N].

A continuación se muestra la implementación del enfoque anterior: 

C++

// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to calculate the total
// number of arrays
int calculate(int position, int used, int unused, int P,
              int M, vector<vector<vector<int> > >& dp)
{
    // If the size of the array is P
    if (position == P) {
        // Check if all elements are
        // used atlease once
        return unused == 0 ? 1 : 0;
    }
 
    // Check if this state is already
    // calculated
    if (dp[position][used][unused] != -1)
        return dp[position][used][unused];
 
    // Initialize the result
    int result = 0;
 
    // Use a number from the list of
    // unused numbers
    if (unused > 0) {
        // There are 'unused' number of
        // favourable choices
        result += calculate(position + 1, used + 1,
                            unused - 1, P, M, dp)
                  * unused;
    }
 
    // Use a number from already present number
    // atlease M distance back
    if (used > M) {
        // There are 'used - M' number of
        // favourable choices
        result += calculate(position + 1,
                            used, unused, P,
                            M, dp)
                  * (used - M);
    }
 
    // Store the result
    return dp[position][used][unused] = result;
}
 
// Function to solve the problem
int solve(int N, int P, int M)
{
    // Initialize DP table : dp[i][j][j]
    // i : current position/index
    // j : number of used elements
    // k : number of unused elements
    vector<vector<vector<int> > > dp(
        101,
        vector<vector<int> >(101,
                             vector<int>(101, -1)));
 
    return calculate(0, 0, N, P, M, dp);
}
// Driver Code
int main()
{
    int N = 2, M = 0, P = 3;
    cout << solve(N, P, M);
}

Java

// Java program for the above approach
import java.io.*;
class GFG
{
 
  // Function to calculate the total
  // number of arrays
  static int calculate(int position, int used, int unused, int P,
                       int M, int dp[][][])
  {
    // If the size of the array is P
    if (position == P)
    {
       
      // Check if all elements are
      // used atlease once
      return unused == 0 ? 1 : 0;
    }
 
    // Check if this state is already
    // calculated
    if (dp[position][used][unused] != -1)
      return dp[position][used][unused];
 
    // Initialize the result
    int result = 0;
 
    // Use a number from the list of
    // unused numbers
    if (unused > 0) {
      // There are 'unused' number of
      // favourable choices
      result += calculate(position + 1, used + 1,
                          unused - 1, P, M, dp)
        * unused;
    }
 
    // Use a number from already present number
    // atlease M distance back
    if (used > M)
    {
       
      // There are 'used - M' number of
      // favourable choices
      result += calculate(position + 1,
                          used, unused, P,
                          M, dp)
        * (used - M);
    }
 
    // Store the result
    return dp[position][used][unused] = result;
  }
 
  // Function to solve the problem
  static int solve(int N, int P, int M)
  {
    // Initialize DP table : dp[i][j][j]
    // i : current position/index
    // j : number of used elements
    // k : number of unused elements
    int[][][] dp = new int[101][101][101];
    for(int i = 0; i < 101; i++)
    {
      for(int j = 0; j < 101; j++)
        for(int k = 0; k < 101; k++)
          dp[i][j][k] = -1;
    }
    return calculate(0, 0, N, P, M, dp);
  }
 
  // Driver Code
  public static void main(String[] args)
  {
    int N = 2, M = 0, P = 3;
    System.out.println(solve(N, P, M));
  }
}
 
// This code is contributed by dwivediyash

Python3

# Python 3 program for the above approach
 
# Function to calculate the total
# number of arrays
def calculate(position, used, unused, P, M, dp):
   
    # If the size of the array is P
    if (position == P):
       
        # Check if all elements are
        # used atlease once
        if unused == 0:
          return 1
        else:
          return 0
 
    # Check if this state is already
    # calculated
    if (dp[position][used][unused] != -1):
        return dp[position][used][unused]
 
    # Initialize the result
    result = 0
 
    # Use a number from the list of
    # unused numbers
    if (unused > 0):
       
        # There are 'unused' number of
        # favourable choices
        result += calculate(position + 1, used + 1,unused - 1, P, M, dp)* unused
 
    # Use a number from already present number
    # atlease M distance back
    if (used > M):
       
        # There are 'used - M' number of
        # favourable choices
        result += calculate(position + 1,used, unused, P,M, dp)* (used - M)
    dp[position][used][unused] = result
 
    # Store the result
    return dp[position][used][unused]
 
# Function to solve the problem
def solve(N, P, M):
   
    # Initialize DP table : dp[i][j][j]
    # i : current position/index
    # j : number of used elements
    # k : number of unused elements
    dp = [[[-1 for i in range(101)] for i in range(101)] for j in range(101)]
 
    return calculate(0, 0, N, P, M, dp)
 
# Driver Code
if __name__ == '__main__':
    N = 2
    M = 0
    P = 3
    print(solve(N, P, M))
     
    # This code is contributed by SURENDRA_GANGWAR.

C#

// C# program for the above approach
using System;
 
public class GFG
{
 
  // Function to calculate the total
  // number of arrays
  static int calculate(int position, int used, int unused, int P,
                       int M, int [,,]dp)
  {
     
    // If the size of the array is P
    if (position == P)
    {
       
      // Check if all elements are
      // used atlease once
      return unused == 0 ? 1 : 0;    
    }
 
    // Check if this state is already
    // calculated
    if (dp[position,used,unused] != -1)
      return dp[position,used,unused];
 
    // Initialize the result
    int result = 0;
 
    // Use a number from the list of
    // unused numbers
    if (unused > 0)
    {
       
      // There are 'unused' number of
      // favourable choices
      result += calculate(position + 1, used + 1,
                          unused - 1, P, M, dp)
        * unused;
    }
 
    // Use a number from already present number
    // atlease M distance back
    if (used > M)
    {
       
      // There are 'used - M' number of
      // favourable choices
      result += calculate(position + 1,
                          used, unused, P,
                          M, dp)
        * (used - M);
    }
 
    // Store the result
    return dp[position,used,unused] = result;
  }
 
  // Function to solve the problem
  static int solve(int N, int P, int M)
  {
     
    // Initialize DP table : dp[i,j,j]
    // i : current position/index
    // j : number of used elements
    // k : number of unused elements
    int[,,] dp = new int[101,101,101];
    for(int i = 0; i < 101; i++)
    {
      for(int j = 0; j < 101; j++)
        for(int k = 0; k < 101; k++)
          dp[i, j, k] = -1;
    }
    return calculate(0, 0, N, P, M, dp);
  }
 
  // Driver Code
  public static void Main(String[] args)
  {
    int N = 2, M = 0, P = 3;
    Console.WriteLine(solve(N, P, M));
  }
}
 
// This code is contributed by shikhasingrajput

Javascript

<script>
        // JavaScript Program to implement
        // the above approach
 
        // Function to calculate the total
        // number of arrays
        function calculate(position, used, unused, P,
            M, dp)
       {
        
            // If the size of the array is P
            if (position == P)
            {
             
                // Check if all elements are
                // used atlease once
                return unused == 0 ? 1 : 0;
            }
 
            // Check if this state is already
            // calculated
            if (dp[position][used][unused] != -1)
                return dp[position][used][unused];
 
            // Initialize the result
            let result = 0;
 
            // Use a number from the list of
            // unused numbers
            if (unused > 0)
            {
             
                // There are 'unused' number of
                // favourable choices
                result += calculate(position + 1, used + 1,
                    unused - 1, P, M, dp)
                    * unused;
            }
 
            // Use a number from already present number
            // atlease M distance back
            if (used > M)
            {
             
                // There are 'used - M' number of
                // favourable choices
                result += calculate(position + 1,
                    used, unused, P,
                    M, dp)
                    * (used - M);
            }
 
            // Store the result
            return dp[position][used][unused] = result;
        }
 
        // Function to solve the problem
        function solve(N, P, M)
        {
         
            // Initialize DP table : dp[i][j][j]
            // i : current position/index
            // j : number of used elements
            // k : number of unused elements
            var dp = new Array(101);
 
            // create 2D
            for (let i = 0; i < dp.length; i++) {
                dp[i] = new Array(101).fill(-1);
            }
 
            // create 3D
            for (let i = 0; i < dp.length; i++) {
                for (let j = 0; j < dp[0].length; j++) {
                    dp[i][j] = new Array(101).fill(-1);
                }
            }
            return calculate(0, 0, N, P, M, dp);
        }
         
        // Driver Code
        let N = 2, M = 0, P = 3;
        document.write(solve(N, P, M));
 
// This code is contributed by Potta Lokesh
 
    </script>
Producción

6

Complejidad del Tiempo: O(N*M*P) (Debido a tres variables dependientes)

Espacio Auxiliar: O(N*M*P) (Tamaño de la array DP)

Publicación traducida automáticamente

Artículo escrito por kartikmodi y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *