Como o @randomA sugeriu, procederemos em duas fases: primeiro encontramos o conjunto de palitos que serão cortados e, em seguida, minimizamos o número de cortes.
Como no caso especial da pergunta, classificamos / os bastões para que . Isso leva tempo . O ( n log n )L1≥L2≥⋯≥LnO(nlogn)
Como @ user1990169 apontou, nunca precisamos cortar um pedaço .i≥k
Na primeira fase, empregamos uma pesquisa binária para encontrar o número , , para que as varas possam ser cortadas em pelo menos pedaços de tamanho (mais alguns pedaços menores) , mas os paus não podem ser cortados em pedaços de tamanho . Isso levará tempo .1 ≤ s ≤ k 1 , … , s k L s 1 , … , s - 1 k L s - 1 O ( k log k )s1≤s≤k1,…,skLs1,…,s−1kLs−1O(klogk)
Se , esse valor é o tamanho ideal e podemos pular a fase dois.Ls−1=Ls
Caso contrário, sabemos que o tamanho ideal satisfaz e se então resulta do corte de pelo menos um dos paus em pedaços de tamanho igual. A fase dois determinará :L s - 1 > o ≥ L s o > L s o ooLs−1>o≥Lso>Lsoo
Para cada bastão , , determine um conjunto de tamanhos candidatos da seguinte maneira: Se cortar em pedaços de tamanho transformar o bastão em pedaços (incluindo o menor, se houver), os candidatos a esse stick são todos os valores , onde e . (Consulte a resposta de @ user1990169 para saber por que esses são os únicos tamanhos de candidatos.)1 ≤ i ≤ s L s r i L ii1≤i≤sLsri j≤riLiLijj≤riLij<Ls−1
Mantenha para cada tamanho de candidato, com que frequência ele ocorreu. Usando uma árvore de pesquisa balanceada, isso pode ser feito em , pois o número total de tamanhos de candidatos é vinculado por .∑ i r i ≤ 2 kO(klogk)∑iri≤2k
Agora, o tamanho do candidato que ocorre com mais frequência e leva a um corte válido é o que nos fornece a solução ideal. Além disso, se qualquer tamanho candidato levar a um corte válido, qualquer tamanho menor levará a um corte válido também.
Portanto, podemos empregar novamente a pesquisa binária para encontrar o maior tamanho de candidato que leva a um corte válido em . Em seguida, iteramos sobre o conjunto de comprimentos de candidatos até esse limite e encontramos o que possui a maior multidão entre eles em .O ( k )O(klogk)O(k)
No total, obtemos um tempo de execução em ou , se ignorarmos (ou não precisarmos fazer) a classificação inicial.O ( k log k )O(nlogn)O(klogk)