web-dev-qa-db-ja.com

動的プログラミング手法を使用して、「ピザピッキングの問題‍」をどのように解決しますか?

ウィンクラーのピザピッキング問題:

  • nスライスの円形のピザパイ。スライスiの面積はS_iです。つまり、面積はパイのピースごとに異なります。
  • 食べる人のアリスとボブは交互にスライスを選びますが、パイに複数のギャップを作るのは失礼です(許可されていないことを考慮してください)。
    • したがって、各イーターは、オープン領域に隣接する2つのスライスの1つを取得するように制限されています。アリスが最初に行き、両方の食べる人はできるだけ多くのパイを探します。

ピザの消費を最大化するためにアリスとボブの両方が完璧にプレーした場合、動的プログラミングアルゴリズムはアリスが食べるパイの量をどのように決定しますか?

私の理解:

一般的なDP問題では、再帰ツリーを使用して、またはより厳密にはDAGを使用して視覚化できるサブ問題を見つけます。ここで、私はここで副問題を見つけるためのリードを見つけていません。

ここで、S_iの特定のセットについて、Aliceが食べるスライスの領域を最大化する必要があります。これは、(n-1)個の順列からPizzaスライスの順列を選択することに依存します。アリスが得るn\2ターンごとに使用可能な2つのオプションから最大領域スライスを選択すると、順列のスライスの総面積が得られます。そのようなすべての順列についてスライスの領域を見つける必要があります。そして、これらのうち最大のもの。

誰かが私を前進させる方法を手伝ってくれる?

9
Amit Shekhar

行に配置されたばかりのスライスを検討することから始め、2つの端のいずれかから選択できます。この場合、あなたが選択する番だとすると、pizzaAmount(slices)

  1. ピザが残っていない場合、結果は0です。
  2. スライスが1つしかない場合、結果はそのスライスになります。
  3. スライスが2つ以上ある場合、結果は次のようになります。

(Python構文を使用)

max(slices[0] + sum(slices[1:]) - pizzaAmount(slices[1:]),
    slices[-1] + sum(slices[:-1]) - pizzaAmount(slices[:-1]))

言い換えれば、両方の選択肢を検討する必要があり、スライスを取得した後、再帰呼び出しの結果を除いて残りのすべてのピザを取得することになります(友達が同じ戦略を使用するため)。

これはDP(またはメモ化)を使用して実装できます。これは、配列が実際に固定されており、最初と最後のスライスインデックスをパラメーターと見なすことができるためです。

元の完全な問題を解決するには、すべてのスライスを開始スライスとして試し、結果が最大になるスライスを選択するだけです。

5
6502

ピザの一部では、F(i,j)を、最初にスライスを選ぶ人が食べることができる最大量として定義します。ピザの一部のスライス_(i,j)_は次のとおりです。

_if i <= j than slices i, i+1, ..., j-1, j
if i > j than slices i, i+1, ..., n-1, n, 1, 2, ..., j-1, j
and we don't define it for whole pizza, abs(i-j) < n-1
_

R(i,j)(2人称での残りの数)をsum(S_x, x in slices(i,j)) - F(i,j)として定義します。

と:

_F(i,i) = S_i,
F(i,j) = max( S_i + R(i+1,j), S_j + R(i,j-1) ),
_

アリスが食べることができる最大値は、次のように計算されます。

_max( S_i + F(i+1, (i-1) if i > 1 else n) ).
_
3
Ante