@randomAが示唆するように、2つのフェーズで処理を進めます。まず、カットするスティックのセットを見つけ、次にカットの数を最小限に抑えます。
質問の特別なケースのように、スティックをソート/命名して、ます。これには時間かかります。 O (N ログN )L1≥ L2≥ ⋯ ≥ LんO(nlogn)
@ user1990169が指摘したように、をカットする必要はありません。i≥k
最初のフェーズでは、バイナリ検索を使用して数、を見つけます。これにより、スティックは、サイズ少なくとも個(さらにいくつかの小さな断片)にカットできます。、ただしスティックはサイズ個にカットできません。これには時間かかります。1 ≤ S ≤ K 1 、... 、S K L S 1 、... 、sは- 1つのK L S - 1 O (k個の対数K )s1≤s≤k1,…,skLs1,…,s−1kLs−1O(klogk)
場合、この値は、最適なサイズであり、我々はフェーズ2を省略することができます。Ls−1=Ls
そうでなければ、我々は知っている最適なサイズ満たすとなら次いで等しい大きさの小片にスティックの少なくとも一方を切断から生じます。フェーズ2はを決定します。L S - 1 > O ≥ L S O > L S O OoLs−1>o≥Lso>Lsoo
各スティック、、次のように候補サイズのセットを決定します。サイズピースにカットすると、スティックがピース(存在する場合は短い方を含む)に変わる場合、この候補がstickはすべての値。ここで、およびです。(これらが唯一の候補サイズである理由については、@ user1990169の回答を参照してください。)1 ≤ I ≤ S L S R I L Ii1≤i≤sLsri J≤RILをILijj≤riLij<Ls−1
候補のサイズごとに、それが発生した頻度を維持します。候補のサイズの総数はによって制限されるため、バランスの取れた検索ツリーを使用すると、これはで実行できます。Σ I 、R I ≤ 2 KO(klogk)∑iri≤2k
現在、最も頻繁に発生し、有効なカットにつながる候補サイズは、最適なソリューションを提供するものです。さらに、候補サイズが有効なカットにつながる場合、小さいサイズも有効なカットにつながります。
したがって、再度バイナリ検索を使用して、有効な切断につながる最大の候補の長さを見つけることができ。次に、このしきい値までの候補の長さのセットを反復処理し、でそれらの中で最大の群集長をもつものを見つけます。O (k )O(klogk)O(k)
合計で、最初のソートを無視する(または実行する必要がない場合、またはでランタイムを取得します。O (k log k )O(nlogn)O(klogk)