アルゴリズムは単純です。まず、問題を で並べ替えv_i
、次に各問題について、区間 内の問題の数を見つけます(v_i-K, v_i]
。これらの数値の最大値が結果です。2 番目のフェーズは で実行できるO(n)
ため、最もコストのかかる操作は並べ替えであり、アルゴリズム全体が になりますO(n log n)
。スプレッドシート内のデータと K=35 に対するアルゴリズムの動作のデモンストレーションについては、こちらをご覧ください。
なぜこれが機能するのか
この問題をグラフの彩色の問題に再定式化しましょう。グラフ G を次のように作成します。頂点が問題になり、2 つの問題 iff の間にエッジが存在します |v_i - v_j| < K
。
このようなグラフでは、独立したセットは、同じ日に実行可能な問題のセットに正確に対応しています。(<=) セットが1日で出来れば、きっと独立セットです。(=>) セットに K 差基準を満たさない 2 つの問題が含まれていない場合は、難易度に従って並べ替えて、この順序で解決できます。このように両方の条件が満たされます。
したがって、グラフ G の色付けは、各色が 1 日に対応する、異なる日の問題のスケジュールに正確に対応することが容易にわかります。
それで、グラフGの色度を見つけたいと思います。これは、グラフが間隔グラフであり、完全なグラフであり、それらの色度がクリークネスに等しく、両方が単純なアルゴリズムで見つけることができることを認識すると簡単になります。
区間グラフは実線上の区間のグラフで、エッジは交差する区間の間にあります。私たちのグラフは、簡単にわかるように、区間グラフです (問題ごとに interval を割り当てます(v_i-K, v_i]
。この区間グラフのエッジが、まさにグラフのエッジであることは容易にわかります)。
補題 1 : 区間グラフには、近傍がクリークを形成する頂点が存在する。
証明は簡単です。すべての中で最も低い上限 (または最も高い下限) を持つ間隔を取るだけです。それと交差する任意の区間の上限はより高いため、最初の区間の上限はそれらすべての交点に含まれます。したがって、それらは互いに交差し、クリークを形成します。した
補題 2 : 誘導されたサブグラフで閉じられ、補題 1 (隣接する頂点がクリークを形成する頂点の存在) のプロパティを持つグラフのファミリでは、次のアルゴリズムは最小限の色付けを生成します。
- 近傍がクリークを形成する頂点xを見つけます。
- グラフからxを削除し、サブグラフ G' を作成します。
- G' を再帰的に色付けする
- 隣に見つからない最小の色で x に色を付ける
証明: (3) では、アルゴリズムは帰納仮説 + 帰納された部分グラフでの私たちの家族の近さによって、部分グラフ G' の最適な色付けを生成します。(4) では、 xの近傍にn
サイズのクリークがある場合にのみ、アルゴリズムは新しい色を選択します。つまり、xの場合、G にはサイズのクリークがあるため、その色度は少なくとも でなければなりません。したがって、アルゴリズムによって頂点に与えられる色は常にです。これは、色付けが最適であることを意味します。(明らかに、アルゴリズムは有効な色を生成します)。したn-1
n
n
<= chromaticity(G)
当然の結果 : 区間グラフは完全です (完全 <=> 色度 == クリークネス)
したがって、Gのクリークネスを見つける必要があります。これは、区間グラフにとって簡単です。区間境界を含まない実線のセグメントを処理し、そこで交差する区間の数を数えるだけです。これは、あなたの場合はさらに簡単です。区間の長さは均一です。これは、この投稿の冒頭で概説したアルゴリズムにつながります。