Vous avez bâtons de longueurs arbitraires, pas nécessairement intégrales.
En coupant quelques bâtons (une coupe coupe un bâton, mais nous pouvons couper aussi souvent que nous le voulons), vous voulez obtenir bâtons tels que:
- Tous ces bâtons ont la même longueur;
- Tous les sticks sont au moins aussi longs que tous les autres sticks.
Notez que nous obtenons bâtons après avoir effectué des coupes
Quel algorithme utiliseriez-vous pour que le nombre de coupes nécessaires soit minimal? Et quel est ce nombre?
À titre d'exemple, prenons et tout . L'algorithme suivant peut être utilisé:
- Ordonner les bâtons par ordre décroissant de longueur tel que .
- Si couper le bâton # 1 en deux morceaux égaux. Il y a maintenant deux bâtons de longueur , qui sont au moins aussi longtemps que les bâtonnets restants .
- Sinon ( ), coupez le bâton # 1 en deux morceaux inégaux de tailles et . Il y a maintenant deux bâtons de longueur , qui est plus longue que et les autres bâtons .L 2 L 1 - L 2 3 … n
Dans les deux cas, une seule coupe suffit.
J'ai essayé de généraliser cela à un plus grand , mais il semble y avoir beaucoup de cas à considérer. Pouvez-vous trouver une solution élégante?
la source
Comme l'a suggéré @randomA, nous procéderons en deux phases: nous trouverons d'abord l'ensemble des bâtons qui seront coupés puis minimiserons le nombre de coupes.
Comme dans le cas particulier de la question, on trie / nomme les bâtons de sorte que . Cela prend du temps O ( n log n ) .L1≥ L2≥ ⋯ ≥ Ln O ( n logn )
Comme l'a souligné @ user1990169, nous n'avons jamais à couper un morceau .i ≥ k
Dans la première phase, nous utilisons une recherche binaire pour trouver le nombre , 1 ≤ s ≤ k , de sorte que les bâtons 1 , … , s peuvent être coupés en au moinss 1 ≤ s ≤ k 1 , … , s morceaux de taille L s (plus quelques petits morceaux), mais les bâtonnets 1 , … , s - 1 ne peuvent pas être coupés en k morceaux de taille L s - 1 . Cela prendra du temps O ( k log k ) .k Ls 1 , … , s - 1 k Ls - 1 O ( k logk )
Si , cette valeur est la taille optimale et nous pouvons sauter la phase deux.Ls - 1= Ls
Sinon, nous savons que la taille optimale satisfait L s - 1 > o ≥ L s et si o > L s alors o résulte de la coupe d'au moins un des bâtons en morceaux de taille égale. La phase deux déterminera o :o Ls - 1> o ≥ Ls o > Ls o o
Pour chaque bâton , 1 ≤ i ≤ s , déterminez un ensemble de tailles candidates comme suit: Si la découpe en morceaux de taille L s transforme le bâton en morceaux r i (y compris le plus court, le cas échéant), alors les candidats pour ce bâton sont toutes les valeurs L ije 1 ≤ i ≤ s Ls rje , oùj≤rietLiLjej j ≤ rje . (Voirla réponse de @ user1990169pour savoir pourquoi ce sont les seules tailles candidates.)Ljej< Ls - 1
Conservez pour chaque taille de candidat, combien de fois cela s'est produit. En utilisant un arbre de recherche équilibré, cela peut être fait dans , car le nombre total de tailles candidates est lié par ∑ i r i ≤ 2 k .O ( k logk ) ∑jerje≤ 2 k
Maintenant, la taille candidate qui s'est produite le plus souvent et conduit à une coupe valide est celle qui nous donne la solution optimale. En outre, si une taille candidate conduit à une coupe valide, toute taille plus petite entraînera également une coupe valide.
Nous pouvons donc à nouveau utiliser la recherche binaire pour trouver la plus grande longueur candidate qui mène à une coupe valide dans . Ensuite, nous itérons sur l'ensemble des longueurs candidates jusqu'à ce seuil et trouvons celui avec la plus grande multitude parmi eux dans O ( k ) .O ( k logk ) O ( k )
Au total, nous obtenons un runtime en , ou O ( k log k ) , si nous ignorons (ou n'avons pas à le faire) le tri initial.O ( n logn ) O ( k logk )
la source
Après avoir commandé les bâtons dans l'ordre décroissant de leur longueur, un bâton ne sera coupé que si tous les bâtons L 1Lje a été coupé.L1, L2, . . . Li - 1
Maintenant que , nous ne ferons aucune coupe sur les bâtonsk < n , car nous pouvons toujours avoir k bâtons de longueur L k .Lk k Lk
Alors maintenant, au lieu de , nous avons affaire à seulement kn sticks (en ajoutant éventuellement le k -th stick dans son ensemble), et le nombre maximum de coupes qui seront nécessaires dans le pire des cas = k - 1 .k - 1 k = k - 1
De plus, si le nombre optimal de coupes est , alors il doit y avoir au moins un ensemble de bâtons parmi ces k - 1 bâtons qui doivent être pris dans leur ensemble à partir de 1 bâton d'origine< k - 1 k - 1 (soit en parties ou en 1 pièce) , c'est-à-dire qu'aucune partie de ce bâton d'origine ne doit être laissée «non prise». En effet, selonleprincipe dupigeonnier, il doit y avoir au moins 1 coupe qui doit produire plus d'un bâton valide.
Vous pouvez ensuite effectuer deux boucles imbriquées (les deux jusqu'à ). La boucle extérieure doit indiquer le numéro de bâtonk dont toutes les parties doivent être prises et la boucle intérieure doit indiquer le nombre de pièces j constituées de ce bâton.
Pour chaque taille L ije j Ljej L1
vérifiez si vous pouvez obtenir des k bâtons réalisables en coupant les bâtonsL1en séquence et si possible, mettez à jour les coupes minimales requises jusqu'à présent si le nombre actuel requis est inférieur.
La complexité totale de l'algorithme ci-dessus estO ( n l o g( n ) + k3)
la source
L'idée de haut niveau serait la recherche binaire.
La taille de chacun des k bâtons demandés sera au moins le plus petit bâtonnet et au plus le plus gros. Pour cette raison, nous procédons en utilisant une recherche binaire sur la taille du bâton du milieu, voyons quel nombre nous pouvons obtenir, si ce k ' est supérieur au k donné, alors nous savons que nous devons choisir une nouvelle taille de référence candidate. Nous passons donc au plus grand ou au plus petit en utilisant un nouveau bâton de référence. On s'arrête quand k ′ est inférieur à kk′ k′ k k′ k
Une fois que nous avons trouvé le bâton de référence approprié, il y a un cas d'angle où nous aurions besoin d'affiner davantage la taille. Nous pouvons trier tous les bâtons coupés par le nombre de coupes sur eux et la taille du bâton. Choisissez celui avec le moins de coupes et la taille la plus petite. Réduisez le nombre de coupes sur ce bâton de 1 et faites tous les sous-bâtons de cette taille égale. Ce sera la nouvelle taille de référence, vérifiez si cette nouvelle taille peut conduire à une taille acceptable. J'avoue, je ne sais pas comment limiter le temps de course dans ce cas.k′
J'espère que je peux voir quelque chose d'utile à partir d'autres réponses.
la source