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>
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