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≥ ⋯ ≥ LnO ( 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 moinss1 ≤ s ≤ k1 , … , 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 ) .kLs1 , … , s - 1kLs - 1O ( 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 :oLs - 1> o ≥ Lso > Lsoo
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 ije1 ≤ i ≤ sLsrje , oùj≤rietLiLjejj ≤ 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 )