5

n 個の整数を持つ配列 A が与えられます。1 回で、次の操作を任意の連続する部分配列 A[l..r] に適用できます。部分配列 A[l..r] のすべての A i (l <= i <= r) 中央値に代入します。max を A の最大整数とします。A をそれぞれ値 max を持つ n 個の整数の配列に変更するために必要な操作の最小数を知りたいです。たとえば、 A = [1, 2, 3] とします。[3, 3, 3] に変更します。これは 2 つの操作で行うことができます。最初は部分配列 A[2..3] (その後、 A は [1, 3, 3] に等しい) に対して、次に A[1..3] に対する操作です。また、ある配列 A に対して次のように中央値が定義されます。B を同じ配列 A としますが、減少しない順序でソートします。A の中央値は B m (1 ベースのインデックス) で、m は (n div 2)+1 に等しくなります。ここで「div」は整数除算演算です。したがって、5 つの要素を持つソート済み配列の場合、

N の最大値は 30 であるため、ブルート フォーシングを考えた結果、より良い解決策が得られる可能性があります。

4

3 に答える 3

5

各反復で最大要素を含むサブ配列のサイズを2倍にすることができます。最初の反復の後、最大値を含むサイズ2のサブ配列があります。次に、これら2つの要素を含むサイズ4のサブ配列に操作を適用し、最大値を含むサイズ4のサブ配列を作成します。次に、サイズ8のサブアレイなどに適用します。配列をlog2(N)演算で入力します。これは、最適です。Nが30の場合、5回の操作で十分です。

これは、各反復で可能な限り多くの要素を設定するため、最悪の場合(つまり、1つの要素のみが最大である場合)に最適です。

アップデート1:4秒と8秒を少し台無しにしたことに気づきました。修正しました。

アップデート2:例を示します。配列サイズ10、開始状態:

[6 1 5 9 3 2 0 7 4 8]

2つのナインを取得するには、ナインを含むサイズ2のサブアレイでopを実行します。たとえば、A[4…5]は次のようになります。

[6 1 5 9 9 2 0 7 4 8]

次に、4…5を含むサイズ4のサブアレイで実行します。たとえば、A [2…5]で実行すると、次のようになります。

[6 9 9 9 9 2 0 7 4 8]

サイズ8のサブアレイ、たとえばA [1…8]で、次のようになります。

[9 9 9 9 9 9 9 9 4 8]

今度は2倍にすると16ナインになりますが、ポジションは10しかないので、A [1…10]でラウンドすると、次のようになります。

[9 9 9 9 9 9 9 9 9 9]

更新3:これは最悪の場合にのみ最適であるため、実際には、すべての入力に対して最小数の操作を見つける方法を求める元の質問に対する回答ではありません。私は、ブルートフォーシングについての文を、操作の最小シーケンスを見つけることではなく、中央値の操作を使用したブルートフォーシングについてであると誤解しました。

于 2012-05-08T13:46:38.897 に答える
1

問題設定者のアプローチは指数関数的に複雑です。N=30 にしてはかなり良いです。しかし、より大きなサイズの場合はそうではありません。指数時間解を見つける方が面白いと思います。そして、O(N 4 ) の複雑さを持つものを見つけました。

このアプローチは、最適解が連続する最大要素のいくつかのグループから始まり、配列全体が最大値で満たされるまでこの単一のグループのみを拡張するという事実を使用します。

この事実を証明するには、連続する最大要素の 2 つの開始グループを取り、それらが 1 つのグループに統合されるまで最適な方法でそれぞれを拡張します。グループ 1 がサイズ M に成長するために X ターンを必要とし、グループ 2 が同じサイズ M に成長するために Y ターンを必要とし、ターン X + Y + 1 でこれらのグループがマージするとします。結果は、少なくとも M * 4 のサイズのグループです。ここで、グループ 2 のターン Y の代わりに、グループ 1 の追加のターン X + 1 を作成します。この場合、グループのサイズは、少なくとも M * 2 で、最大 M / 2 です。 (最初に最大要素を数えたとしても、それはステップ Y に含まれる可能性があります)。この変更の後、ターン X + Y + 1 で、マージされたグループのサイズは、最初のグループ拡張の結果として少なくとも M * 4 になり、これに 2 番目のグループから少なくとも 1 つの要素が追加されます。したがって、ここで単一のグループを拡張すると、同じステップ数でより大きなグループが生成されます (Y > 1 の場合、必要な手順も少なくて済みます)。これはグループ サイズ (M) が等しい場合に機能するため、等しくないグループの場合はさらに効果的です。この証明は、いくつかのグループ (2 つ以上) の場合に拡張できます。

連続する最大要素の 1 つのグループを操作するには、グループの開始位置と終了位置の 2 つの値のみを追跡する必要があります。つまり、三角行列を使用してすべての可能なグループを格納できるため、動的計画法アルゴリズムを使用できます。

擬似コード:

For each group of consecutive maximal elements in original array:
  Mark corresponding element in the matrix and clear other elements
  For each matrix diagonal, starting with one, containing this element:
    For each marked element in this diagonal:
      Retrieve current number of turns from this matrix element
      (use indexes of this matrix element to initialize p1 and p2)
      p2 = end of the group
      p1 = start of the group
      Decrease p1 while it is possible to keep median at maximum value
      (now all values between p1 and p2 are assumed as maximal)
      While p2 < N:
        Check if number of maximal elements in the array is >= N/2
          If this is true, compare current number of turns with the best result \
               and update it if necessary
          (additional matrix with number of maximal values between each pair of
            points may be used to count elements to the left of p1 and to the
            right of p2)
        Look at position [p1, p2] in the matrix. Mark it and if it contains \
            larger number of turns, update it
        Repeat:
          Increase p1 while it points to maximal value
          Increment p1 (to skip one non-maximum value)
          Increase p2 while it is possible to keep median at maximum value
        while median is not at maximum value

アルゴリズムを単純にするために、グループが位置 0 で開始するか、位置 N で終了し、初期化をスキップし、最適化を行わなかった特殊なケースについては言及しませんでした。

于 2012-05-11T23:18:45.753 に答える