Tengo una matriz a[n]. El número nlo ingresamos nosotros. Necesito encontrar el producto mínimo de a[i]y a[j]si:
1) abs(i - j) > k
2) a[i] * a[j]se minimiza
Aquí está mi solución (muy ingenua):
#include <iostream>
using namespace std;
#define ll long long
int main() {
    ll n,k; cin >> n >> k;
    ll a[n]; for(ll i=0;i<n;i++) cin >> a[i];
    ll mn; bool first = true;
    for(ll i=0;i<n;i++) {
        for(ll j=0;j<n;j++) {
            if(i!=j)
            if(abs(i-j) > k) {
                if(first) {
                    mn = a[i]*a[j];
                    first = false;
                } else if(a[i]*a[j] < mn) mn = a[i]*a[j];
            }
        }
    }
    cout << mn << endl;
}¿Pero quiero saber si hay alguna forma más rápida de encontrar un producto mínimo con distancia?
                    
                        c++
                                algorithm
                                optimization
                                minimum
                                
                    
                    
                        Mouvre
fuente
                
                fuente

std::vector? @Scheff: la clasificación destruiría las relaciones originales de "distancia".if (i!=j) if (abs(i - j) > k)puede ser eliminado. Sólo empezar el bucle interior en i + k + 1:for (ll j = i + k + 1; j < n; ++j). La verificación con tambiénfirstse puede eliminar simnse inicializa antes, por ejemplo, conmn = a[0] * a[k + 1];. (Tal vez,kdebería verificarseninicialmente para hacer esto a prueba de balas). Pero sigue siendo O (N²). Esto debe ser factible más rápido ...Respuestas:
Suponiendo que haya al menos un par de elementos que satisfagan las condiciones y que no se desborde la multiplicación de dos elementos, esto puede hacerse en el
Theta(n-k)tiempo y elTheta(1)espacio en el peor y el mejor de los casos, con algo como esto:Esto es óptimo en términos de la complejidad asintótica del peor de los casos, tanto para el tiempo como para el espacio, porque el producto óptimo puede estar
a[0]con cualquiera de losn-(k+1)elementos en la distancia, al menosk+1, por lon-(k+1)que cualquier algoritmo que resuelva el problema debe leer al menos los enteros.La idea detrás del algoritmo es la siguiente:
El producto óptimo utiliza dos elementos de
a, suponga que estos sona[r]ya[s]. Sin pérdida de generalidad podemos suponer ques > rdado que el producto es conmutativo.Debido a la restricción,
abs(s-r) > kesto implica ques >= k+1. Ahoraspodría ser cada uno de los índices que satisfagan esta condición, por lo que iteramos sobre estos índices. Esa es la iteraciónien el código que se muestra, pero se cambia pork+1conveniencia (realmente no importa). Para cada iteración, necesitamos encontrar el producto óptimo que incluya eli+k+1mayor índice y compararlo con la mejor estimación anterior.Los índices posibles para emparejar
i+k+1son todos índices menores o igualesidebido al requisito de distancia. Tendríamos que repetir todo esto también, pero eso es innecesario porque el mínimo dea[i+k+1]*a[j]overjen fijoies igual amin(a[i+k+1]*max(a[j]), a[i+k+1]*min(a[j]))debido a la monotonicidad del producto (tomando el mínimo con respecto al mínimo y al máximo sobrea[j]cuentas para los dos posibles signos de,a[i+k+1]o equivalentemente, las dos posibles direcciones de monotonicidad.)Dado que el conjunto de
a[j]valores sobre el que optimizamos aquí es justo{a[0], ..., a[i]}, que simplemente crece por un elemento (a[i]) en cada iteración dei, simplemente podemos realizar un seguimiento demax(a[j])ymin(a[j])con variables individuales actualizándolas sia[i]es mayor o menor que los valores óptimos anteriores. Esto se hace conback_maxyback_minen el ejemplo de código.El primer paso de la iteración (
i=0) se omite en el bucle y, en su lugar, se realiza como inicialización de las variables.fuente
a[i+k+1]son el mínimo y el máximo.No estoy seguro sobre lo más rápido .
Para el problema más simple sin i <j - k , el producto mínimo se encuentra entre los productos de pares de los dos elementos más pequeños y más grandes.
Entonces, (lo siguiente es demasiado complicado, ver la respuesta de nuez )
(• rechazar si k ≤ n
• inicializar minProduct a a [0] * a [k + 1])
comenzando con {} y {a [ j ] | k ≤ j }
min ( upToI ) × min ( beyondIplusK ), min ( upToI ) × max ( beyondIplusK ),
max ( upToI ) × min ( beyondIplusK ) y max ( upToI ) × max ( beyondIplusK )
fuente
minUpto,maxUpto,minBeyond,maxBeyond(Se puede crear en dos iteraciones)? Luego, en la tercera iteración, para cada índice, encuentre la multiplicación mínima posible.Para "magnitud mínima"
Encuentre los 2 elementos de "magnitud más pequeña" y luego (después de haber encontrado dos ceros o buscado en toda la matriz), multiplíquelos.
Para el "valor más bajo" sin la
abs(i - j) > kparteHay 3 posibilidades:
los dos números negativos más altos (magnitud más pequeña)
los dos números no negativos más bajos (magnitud más pequeña)
el número negativo más bajo (magnitud más grande) y el número no negativo más alto (magnitud más grande)
Puede buscar los 6 valores y descubrir los productos y cuál es el mejor al final.
Sin embargo; tan pronto como vea un cero, sabe que no necesita saber más acerca de las 2 primeras posibilidades; y tan pronto como veas un número negativo y uno no negativo, sabrás que solo te importa la tercera posibilidad.
Esto lleva a una máquina de estados finitos con 3 estados: "preocuparse por las 3 posibilidades", "la respuesta es cero a menos que se vea un número negativo" y "solo preocuparse por la última posibilidad". Esto se puede implementar como un conjunto de 3 bucles, donde 2 de los bucles saltan a (
goto) el centro de otro bucle cuando cambia el estado (de la máquina de estados finitos).Específicamente, podría parecerse a algo vagamente (no probado):
Para el "valor más bajo" con la
abs(i - j) > kparteEn este caso todavía tienes las 3 posibilidades; y podría hacerlo funcionar con el mismo enfoque de "3 bucles con máquina de estados finitos", pero se vuelve demasiado desordenado / feo. Para este caso, es probable que una mejor alternativa escanee previamente la matriz para determinar si hay ceros y si todos son negativos o todos positivos; para que después de la exploración previa pueda saber si la respuesta es cero o seleccionar un bucle diseñado solo para la posibilidad específica.
fuente