J'ai un tableau a[n]
. Nous saisissons le numéro n
. J'ai besoin de trouver le produit minimal a[i]
et a[j]
si:
1) abs(i - j) > k
2) a[i] * a[j]
est minimisé
Voici ma solution (très naïve):
#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;
}
Mais je veux savoir s'il existe un moyen plus rapide de trouver un produit minimal à distance?
c++
algorithm
optimization
minimum
Mouvre
la source
la source
std::vector
? @Scheff - le tri détruirait les relations "de distance" d'origine.if (i!=j) if (abs(i - j) > k)
peut être éliminé. Il suffit de commencer la boucle interne à i + k + 1:for (ll j = i + k + 1; j < n; ++j)
. Le chèque avecfirst
peut également être éliminé s'ilmn
est initialisé avant, par exemple avecmn = a[0] * a[k + 1];
. (Peut-être,k
devrait être vérifié aun
départ pour rendre ce pare-balles.) Mais c'est toujours O (N²). Cela doit être faisable plus rapidement ...Réponses:
En supposant qu'il y ait au moins une paire d'éléments satisfaisant aux conditions et qu'aucune multiplication de deux éléments ne déborde, cela peut être fait dans le pire et le meilleur des cas dans le
Theta(n-k)
temps et l'Theta(1)
espace, avec quelque chose comme ceci:C'est optimal en termes de complexité asymptotique dans le pire des cas, à la fois dans le temps et dans l'espace, car le produit optimal peut être
a[0]
avec au moins l'un desn-(k+1)
éléments à distancek+1
, donc au moins lesn-(k+1)
entiers doivent être lus par tout algorithme résolvant le problème.L'idée derrière l'algorithme est la suivante:
Le produit optimal utilise deux éléments de
a
, supposons que ce soienta[r]
eta[s]
. Sans perte de généralité, nous pouvons supposer ques > r
puisque le produit est commutatif.En raison de la restriction,
abs(s-r) > k
cela implique ques >= k+1
. Maintenant,s
chacun des indices pourrait satisfaire à cette condition, donc nous itérons sur ces indices. C'est l'itérationi
dans le code affiché, mais elle est décaléek+1
pour plus de commodité (peu importe). Pour chaque itération, nous devons trouver le produit optimal impliquanti+k+1
le plus grand indice et le comparer avec la meilleure estimation précédente.Les indices possibles à coupler
i+k+1
sont tous des indices plus petits ou égaux eni
raison de la distance requise. Nous aurions besoin d'itérer sur tous ces éléments également, mais cela n'est pas nécessaire car le minimum dea[i+k+1]*a[j]
surj
à fixei
est égal à enmin(a[i+k+1]*max(a[j]), a[i+k+1]*min(a[j]))
raison de la monotonie du produit (en prenant le minimum en ce qui concerne à la fois le minimum et le maximum sur lesa[j]
comptes pour les deux possibles signesa[i+k+1]
ou équivalents des deux directions possibles de la monotonie.)Puisque l'ensemble de
a[j]
valeurs sur lesquelles nous optimisons ici est juste{a[0], ..., a[i]}
, qui croît simplement d'un élément (a[i]
) à chaque itération dei
, nous pouvons simplement garder une trace demax(a[j])
etmin(a[j])
avec des variables uniques en les mettant à jour si ellesa[i]
sont plus grandes ou plus petites que les valeurs optimales précédentes. Cela se fait avecback_max
etback_min
dans l'exemple de code.La première étape de l'itération (
i=0
) est ignorée dans la boucle et effectuée à la place comme initialisation des variables.la source
a[i+k+1]
sont le minimum et le maximum.Je ne sais pas trop vite .
Pour le problème plus simple sans i <j - k , le produit minimal est parmi les produits des paires des deux éléments les plus petits et les plus grands.
Donc, (ce qui suit est trop compliqué, voir la réponse de Walnut )
(• rechigner si k ≤ n
• initialiser minProduct à a [0] * a [k + 1])
commençant par {} et {a [ j ] | k ≤ j }
min ( upToI ) × min ( BeyondIplusK ), min ( upToI ) × max ( BeyondIplusK ),
max ( upToI ) × min ( BeyondIplusK ) et max ( upToI ) × max ( BeyondIplusK )
la source
minUpto
,maxUpto
,minBeyond
,maxBeyond
(Vous pouvez créer en deux itérations)? Ensuite, dans la troisième itération, pour chaque index, trouvez la multiplication minimale possible.Pour "magnitude minimale"
Trouvez les 2 éléments de "plus petite amplitude", puis (après avoir trouvé deux zéros ou fouillé l'ensemble du tableau), multipliez-les.
Pour la "valeur la plus basse" sans
abs(i - j) > k
pièceIl y a 3 possibilités:
les deux nombres négatifs les plus élevés (la plus petite ampleur)
les deux nombres non négatifs les plus bas (de plus petite ampleur)
le nombre négatif le plus bas (la plus grande ampleur) et le nombre non négatif le plus élevé (la plus grande ampleur)
Vous pouvez rechercher les 6 valeurs et déterminer les produits et ce qui est le mieux à la fin.
Toutefois; dès que vous voyez un zéro, vous savez que vous n'avez plus besoin d'en savoir plus sur les 2 premières possibilités; et dès que vous voyez un nombre négatif et un nombre non négatif, vous savez que vous ne vous souciez que de la troisième possibilité.
Cela conduit à une machine à états finis avec 3 états - "se soucie de toutes les 3 possibilités", "la réponse est zéro à moins qu'un nombre négatif ne soit vu" et "ne se soucie que de la dernière possibilité". Cela peut être implémenté comme un ensemble de 3 boucles, où 2 des boucles sautent dans (
goto
) le milieu d'une autre boucle lorsque l'état (de la machine à états finis) change.Plus précisément, cela pourrait ressembler à quelque chose de vaguement (non testé):
Pour "valeur la plus basse" avec la
abs(i - j) > k
pièceDans ce cas, vous avez encore les 3 possibilités; et pourrait le faire fonctionner avec la même approche "3 boucles avec machine à états finis" mais cela devient trop désordonné / moche. Dans ce cas, une meilleure alternative est susceptible de pré-scanner le tableau pour déterminer s'il y a des zéros et s'ils sont tous négatifs ou tous positifs; de sorte qu'après le pré-scan, vous pouvez savoir que la réponse est zéro ou sélectionner une boucle conçue pour la seule possibilité spécifique.
la source