Étant donné deux chaînes , nous écrivons pour leur concaténation. Étant donné une chaîne et entier , nous écrivons pour la concaténation de copies de . Maintenant donné une chaîne, nous pouvons utiliser cette notation pour la 'comprimer', c'est-à-dire que peut être écrit comme . Appelons le poids d'une compression le nombre de caractères qui y apparaissent, donc le poids de est deux, et le poids de (une compression d' ) est de trois (séparé ( ( A ) 2 B 2 ) ( A B ) 2 A A B A B A A sont comptés séparément).
Considérons maintenant le problème du calcul de la compression "la plus légère" d'une chaîne donnée avec . Après réflexion, il existe une approche de programmation dynamique évidente qui s'exécute en ou selon l'approche exacte.
Cependant, on m'a dit que ce problème peut être résolu en temps , bien que je ne trouve aucune source sur la façon de le faire. Plus précisément, ce problème a été évoqué lors d'un récent concours de programmation (problème K ici , deux dernières pages). Au cours de l'analyse, un algorithme été présenté et, à la fin, la borne pseudo quadratique a été mentionnée ( ici à la marque de quatre minutes). Malheureusement, le présentateur n'a fait référence qu'à «un lemme de combinatoire de mots compliqué», alors maintenant je suis venu ici pour demander la solution :-)
la source
Réponses:
Si je ne vous comprends pas, je pense que la factorisation du coût minimum peut être calculée en temps comme suit.O(n2)
Pour chaque indice i, nous calculerons un ensemble de valeurs pour comme suit. Soit le plus petit entier tel qu'il existe un entier satisfaisantPour ce , soit le plus grand avec cette propriété. Si aucun n'existe, définissez afin que nous sachions qu'il y a zéro pour cet indice.(pℓi,rℓi) ℓ=1,2,… p1i≥1 r≥2 S[i−rp1i+1,i−p1i]=S[i−(r−1)p1i+1,i]. p1i r1i r pi Li=0 (pℓi,rℓi)
Soit le plus petit entier strictement supérieur à satisfaisant, de même, pour certains . Comme précédemment, prenez pour être le maximum ayant fixé . En général, est le plus petit nombre strictement supérieur à . Si aucun tel n'existe, alors .p2i (r1i−1)p1i S[i−r2ip2i+1,i−p2i]=S[i−(r2i−1)p2i+1,i] r2i≥2 r2i p2i pℓi (rℓ−1i−1)pℓ−1i pℓi Li=ℓ−1
Notez que pour chaque indice i, nous avons car les valeurs de augmentent géométriquement avec . (si existe, il n'est pas seulement strictement plus grand que mais plus grand que celui d'au moins Ceci établit l'augmentation géométrique. )Li=O(log(i+1)) pℓi ℓ pℓ+1i (rℓi−1)pℓi pℓi/2
Nous avons déjà observé ci-dessus que en délimitant la somme terme par terme. Mais en fait, si nous regardons la somme entière, nous pouvons prouver quelque chose de plus net.∑jLj=O(∑jlog(j+1))=Θ(nlogn)
Considérons l'arbre de suffixe de l'inverse de (c'est-à-dire l'arbre de préfixe de S). Nous facturerons chaque contribution à la somme à un bord de afin que chaque bord soit facturé au plus une fois. Chargez chaque au bord émanant de et allant vers . Ici est la feuille de l'arbre préfixe correspondant à et nca désigne l'ancêtre commun le plus proche.T(S←) S ∑iLi T(S←) pji nca(v(i),v(i−pji)) v(i−pji) v(i) S[1..i]
Cela montre que . Les valeurs peuvent être calculées dans le temps par une traversée de l'arbre des suffixes mais je laisserai les détails à une édition ultérieure si quelqu'un est intéressé.O(∑iLi)=O(n) (pji,rji) O(n+∑iLi)
Faites-moi savoir si cela a du sens.
la source
Il y a votre chaîne initiale S de longueur n. Voici le pseudo-code de la méthode.
J'ai intentionnellement donné peu de détails sur les "crochets d'extrémité" car il faut beaucoup d'étapes pour empiler et désempiler, ce qui rendrait la méthode principale peu claire. L'idée est de tester une éventuelle contraction supplémentaire à l'intérieur de la première. par exemple ABCBCABCBC => (ABCBC) ² => (A (BC) ²) ².
Donc, le point principal est de chercher d'abord les grandes périodes. Notez que S [i] est le ième terme de S qui saute tout "(", ")" ou puissance.
C'est globalement O (n²log (n)).
la source