Número de permutación con inversiones K | conjunto 2

Dados dos números enteros N y K , la tarea es contar el número de permutaciones de los primeros N números naturales que tienen exactamente K inversiones. Dado que el conteo puede ser muy grande, imprímalo módulo 10 9 + 7 .

Una inversión se define como un par a[i], a[j] tal que a[i] > a[j] e i < j .

Ejemplos:

Entrada: N = 3, K = 2
Salida: 2
Explicación:
Todas las permutaciones para N = 3 son 321, 231, 213, 312, 132, 123.
De las cuales solo 231 y 312 tienen 2 inversiones como:

  • 231: 2 > 1 y 3 > 1
  • 312: 3 > 1 y 3 > 2.

Por lo tanto, ambos cumplen la condición de tener exactamente K inversiones.

Entrada: N = 5, K = 5
Salida: 22

 

Enfoque ingenuo: consulte la publicación anterior para conocer el enfoque más simple posible para resolver el problema. 
Complejidad temporal: O(N*N!)
Espacio auxiliar: O(1)

Programación dinámica utilizando el enfoque de arriba hacia abajo: consulte la publicación anterior de este artículo para el enfoque de arriba hacia abajo. 
Complejidad de Tiempo: O(N*K 2 )
Espacio Auxiliar: O(N*K)

Programación dinámica utilizando el enfoque ascendente:

Ilustración:

Por ejemplo: N = 4, K = 2

N – 1 = 3, K 0 = 0 … 123 => 1423
N – 1 = 3, K 1 = 1 … 213, 132 => 2143, 1342
N – 1 = 3, K 2 = 2 … 231, 312 => 2314, 3124
Entonces la respuesta es 5 .

El valor máximo se toma entre (K – N + 1) y 0 ya que no se pueden obtener K inversiones si el número de inversiones en permutación de (N – 1) números es menor que K – (N – 1) como máximo (N – 1) Se pueden obtener nuevas inversiones sumando el número N al principio.

Siga los pasos a continuación para resolver el problema:

  • Cree una array auxiliar dp[2][K + 1] donde dp[N][K] almacena todas las permutaciones de (N – 1) números con K = (max(K – (N – 1), 0) a K) inversiones, sumando N número con ellos una sola vez.
  • El uso de dp[i % 2][K] intercambiará la iteración entre dos filas y tomará j = Max(K – (N – 1), 0) . Entonces dp[N[K] = dp[N-1][j] + dp[N-1][j+1] + …. + dp[N – 1][K] .
  • Para calcular dp[N][K] no es necesario realizar esta iteración adicional de K , ya que se puede obtener en O(1) a partir de dp[N][K – 1] . Entonces la relación de recurrencia viene dada por:
    • dp[N][K] = dp[N][K – 1] + dp[N – 1][K] – dp[N – 1][máx(K – (N – 1), 0) – 1]
  • Itere dos bucles anidados usando la variable i y j sobre N y K respectivamente y actualice cada estado de dp según la relación de recurrencia anterior.
  • Imprima el valor de dp[N%2][K] después de los pasos anteriores como resultado.

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 count permutations with
// K inversions
int numberOfPermWithKInversion(
    int N, int K)
{
    // Store number of permutations
    // with K inversions
    int dp[2][K + 1];
  
    int mod = 1000000007;
  
    for (int i = 1; i <= N; i++) {
        for (int j = 0; j <= K; j++) {
  
            // If N = 1 only 1 permutation
            // with no inversion
            if (i == 1)
                dp[i % 2][j] = (j == 0);
  
            // For K = 0 only 1 permutation
            // with no inversion
            else if (j == 0)
                dp[i % 2][j] = 1;
  
            // Otherwise Update each dp
            // state as per the reccurrance
            // relation formed
            else
                dp[i % 2][j]
                    = (dp[i % 2][j - 1] % mod
                       + (dp[1 - i % 2][j]
                          - ((max(j - (i - 1), 0) == 0)
                                 ? 0
                                 : dp[1 - i % 2]
                                     [max(j - (i - 1), 0)
                                      - 1])
                          + mod)
                             % mod)
                      % mod;
            ;
        }
    }
  
    // Print final count
    cout << dp[N % 2][K];
}
  
// Driver Code
int main()
{
    // Given N and K
    int N = 3, K = 2;
  
    // Function Call
    numberOfPermWithKInversion(N, K);
  
    return 0;
}

Java

// Java program for the above approach
import java.io.*;
  
class GFG{
  
// Function to count permutations with
// K inversions
static void numberOfPermWithKInversion(int N, int K)
{
      
    // Store number of permutations
    // with K inversions
    int[][] dp = new int[2][K + 1];
  
    int mod = 1000000007;
  
    for(int i = 1; i <= N; i++) 
    {
        for(int j = 0; j <= K; j++) 
        {
              
            // If N = 1 only 1 permutation
            // with no inversion
            if (i == 1)
            {
                dp[i % 2][j] = (j == 0) ? 1 : 0;
            }
  
            // For K = 0 only 1 permutation
            // with no inversion
            else if (j == 0)
                dp[i % 2][j] = 1;
  
            // Otherwise Update each dp
            // state as per the reccurrance
            // relation formed
            else
                {
                 int maxm = Math.max(j - (i - 1));
             dp[i % 2][j] = (dp[i % 2][j - 1] % mod +
                               (dp[1 - i % 2][j] - 
                               ((Math.max(j - (i - 1), 0) == 0) ?
                                   0 : dp[1 - i % 2][maxm, 0) - 1]) +
                                         mod) % mod) % mod;
}
        }
    }
      
    // Print final count
    System.out.println (dp[N % 2][K]);
}
  
// Driver Code
public static void main(String[] args)
{
      
    // Given N and K
    int N = 3, K = 2;
  
    // Function Call
    numberOfPermWithKInversion(N, K);
}
}
  
// This code is contributed by akhilsaini

Python3

# Python3 program for the above approach
  
# Function to count permutations with
# K inversions
def numberOfPermWithKInversion(N, K):
      
    # Store number of permutations
    # with K inversions
    dp = [[0] * (K + 1)] * 2
  
    mod = 1000000007
  
    for i in range(1, N + 1):
        for j in range(0, K + 1):
              
            # If N = 1 only 1 permutation
            # with no inversion
            if (i == 1):
                dp[i % 2][j] = 1 if (j == 0) else 0
  
            # For K = 0 only 1 permutation
            # with no inversion
            elif (j == 0):
                dp[i % 2][j] = 1
  
            # Otherwise Update each dp
            # state as per the reccurrance
            # relation formed
            else:
                var = (0 if (max(j - (i - 1), 0) == 0)
                         else dp[1 - i % 2][max(j - (i - 1), 0) - 1])
                dp[i % 2][j] = ((dp[i % 2][j - 1] % mod +
                                (dp[1 - i % 2][j] -
                                (var) + mod) % mod) % mod)
  
    # Print final count
    print(dp[N % 2][K])
  
# Driver Code
if __name__ == '__main__':
      
    # Given N and K
    N = 3
    K = 2
  
    # Function Call
    numberOfPermWithKInversion(N, K)
  
# This code is contributed by akhilsaini

C#

// C# program for the above approach
using System;
  
class GFG{
  
// Function to count permutations with
// K inversions
static void numberOfPermWithKInversion(int N, int K)
{
      
    // Store number of permutations
    // with K inversions
    int[,] dp = new int[2, K + 1];
  
    int mod = 1000000007;
  
    for(int i = 1; i <= N; i++)
    {
        for(int j = 0; j <= K; j++) 
        {
              
            // If N = 1 only 1 permutation
            // with no inversion
            if (i == 1)
            {
                dp[i % 2, j] = (j == 0) ? 1 : 0;
            }
  
            // For K = 0 only 1 permutation
            // with no inversion
            else if (j == 0)
                dp[i % 2, j] = 1;
  
            // Otherwise Update each dp
            // state as per the reccurrance
            // relation formed
            else
                dp[i % 2, j] = (dp[i % 2, j - 1] % mod + 
                               (dp[1 - i % 2, j] - 
                               ((Math.Max(j - (i - 1), 0) == 0) ?
                                   0 : dp[1 - i % 2, Math.Max(
                                          j - (i - 1), 0) - 1]) +
                                              mod) % mod) % mod;
        }
    }
  
    // Print final count
    Console.WriteLine(dp[N % 2, K]);
}
  
// Driver Code
public static void Main()
{
  
    // Given N and K
    int N = 3, K = 2;
  
    // Function Call
    numberOfPermWithKInversion(N, K);
}
}
  
// This code is contributed by akhilsaini

Javascript

<script>
  
// Javascript program to implement
// the above approach
  
// Function to count permutations with
// K inversions
function numberOfPermWithKInversion(N, K)
{
        
    // Store number of permutations
    // with K inversions
    let dp = new Array(2);
    // Loop to create 2D array using 1D array
    for (var i = 0; i < dp.length; i++) 
    {
    dp[i] = new Array(2);
    }
    
    let mod = 1000000007;
    
    for(let i = 1; i <= N; i++) 
    {
        for(let j = 0; j <= K; j++) 
        {
                
            // If N = 1 only 1 permutation
            // with no inversion
            if (i == 1)
            {
                dp[i % 2][j] = (j == 0) ? 1 : 0;
            }
    
            // For K = 0 only 1 permutation
            // with no inversion
            else if (j == 0)
                dp[i % 2][j] = 1;
    
            // Otherwise Update each dp
            // state as per the reccurrance
            // relation formed
            else
                dp[i % 2][j] = (dp[i % 2][j - 1] % mod +
                 (dp[1 - i % 2][j] - 
                 ((Math.max(j - (i - 1), 0) == 0) ?
                   0 : dp[1 - i % 2][Math.max(j - 
                          (i - 1), 0) - 1]) +
                             mod) % mod) % mod;
        }
    }
        
    // Print final count
    document.write(dp[N % 2][K]);
}
      
    // Driver Code
       
           // Given N and K
    let N = 3, K = 2;
    
    // Function Call
    numberOfPermWithKInversion(N, K);
    
</script>
Producción: 

2

 

Complejidad temporal: O(N * K)
Espacio auxiliar: O(K)

Publicación traducida automáticamente

Artículo escrito por artiam_99 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 *