ウィンクラーのピザピッキング問題:
n
スライスの円形のピザパイ。スライスi
の面積はS_i
です。つまり、面積はパイのピースごとに異なります。ピザの消費を最大化するためにアリスとボブの両方が完璧にプレーした場合、動的プログラミングアルゴリズムはアリスが食べるパイの量をどのように決定しますか?
私の理解:
一般的なDP問題では、再帰ツリーを使用して、またはより厳密にはDAGを使用して視覚化できるサブ問題を見つけます。ここで、私はここで副問題を見つけるためのリードを見つけていません。
ここで、S_iの特定のセットについて、Aliceが食べるスライスの領域を最大化する必要があります。これは、(n-1)個の順列からPizzaスライスの順列を選択することに依存します。アリスが得るn\2ターンごとに使用可能な2つのオプションから最大領域スライスを選択すると、順列のスライスの総面積が得られます。そのようなすべての順列についてスライスの領域を見つける必要があります。そして、これらのうち最大のもの。
誰かが私を前進させる方法を手伝ってくれる?
行に配置されたばかりのスライスを検討することから始め、2つの端のいずれかから選択できます。この場合、あなたが選択する番だとすると、pizzaAmount(slices)
が
(Python構文を使用)
max(slices[0] + sum(slices[1:]) - pizzaAmount(slices[1:]),
slices[-1] + sum(slices[:-1]) - pizzaAmount(slices[:-1]))
言い換えれば、両方の選択肢を検討する必要があり、スライスを取得した後、再帰呼び出しの結果を除いて残りのすべてのピザを取得することになります(友達が同じ戦略を使用するため)。
これはDP(またはメモ化)を使用して実装できます。これは、配列が実際に固定されており、最初と最後のスライスインデックスをパラメーターと見なすことができるためです。
元の完全な問題を解決するには、すべてのスライスを開始スライスとして試し、結果が最大になるスライスを選択するだけです。
ピザの一部では、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) ).
_