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


9

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

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

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

私の理解:

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

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

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

回答:


5

行に配置されたばかりのスライスを検討することから始め、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(またはメモ化)を使用して実装できます。これは、配列が実際に固定されており、最初と最後のスライスインデックスをパラメーターと見なすことができるためです。

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


ありがとう「6502」。「列に配置されたばかりのスライスを考慮して、両端の1つから選択する」というヒントを利用することで、問題をよりよく視覚化できます。与えられた再発関係は、相手による最適な選択にも対応しています。正式なアルゴリズムを間もなく投稿します。みんなありがとう!!

このアルゴリズムの複雑さの順序は何ですか?0(n * 2 ^ n)?

@Akron:これは、動的プログラミングのアプローチやメモ化がなければ、そうなるでしょう。ただし、doの結果はpizzaAmount残りのスライスの開始インデックスと終了インデックスが何であるかにのみ依存し、あなたとあなたの友人がすでに食べたピザスライスのシーケンスに依存しないため、結果を再計算を回避するための行列。したがって、アルゴリズムの順序はO(n ** 2)です。
6502

誰かがまだ理解に苦労している場合、このリンクは非常に素晴らしい説明があります。
Amit Shekhar、2012

3

ピザの一部について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) ).
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.