동적 프로그래밍 기술을 사용하여“피자 따기 문제”를 어떻게 해결합니까?


9

Winkler의 피자 따기 문제 :

  • n슬라이스 의 원형 피자 파이 . 슬라이스 i가 면적을 갖는 경우 S_i, 즉 면적은 각 파이 조각마다 다릅니다.
  • 먹는 사람 앨리스와 밥은 교대로 조각을 따지 만 파이에 여러 개의 간격을 만드는 것은 무례합니다 (허용되지 않는 것으로 간주).
    • 따라서 각 먹는 사람은 개방 된 영역에 인접한 두 조각 중 하나를 섭취하도록 제한됩니다. 앨리스가 먼저 가고 두 먹는 사람은 가능한 많은 파이를 찾습니다.

Alice와 Bob이 피자 소비를 극대화하기 위해 완벽하게 플레이한다면 동적 프로그래밍 알고리즘이 Alice가 먹는 파이의 양을 어떻게 결정합니까?

내 이해 :

일반적인 DP 문제에서 우리는 재귀 트리를 사용하거나 더 엄격하게 DAG를 사용하여 시각화 할 수있는 하위 문제를 찾는 것으로 진행합니다. 여기에서 하위 문제를 찾을 수있는 리드를 찾지 못했습니다.

여기에서 주어진 S_i 세트에 대해 Alice가 먹는 슬라이스 영역을 최대화해야합니다. 이것은 (n-1) 순열 중 피자 조각 순열을 선택하는 것에 달려 있습니다. 앨리스가 얻을 수있는 모든 n \ 2 회전에서 사용 가능한 두 가지 옵션 중에서 최대 영역 슬라이스를 선택하면 순열에 대한 슬라이스의 전체 영역이 제공됩니다. 이러한 모든 순열에 대해 슬라이스 영역을 찾아야합니다. 그리고 그 중 최대 값.

앞으로 나아가는 방법에 대해 누군가 나를 도울 수 있습니까?

답변:


5

한 줄에 놓은 슬라이스를 고려하여 시작하면 두 끝 중 하나에서 선택할 수 있습니다. 가정하면이 경우는 그 분명 선택하는 당신의 차례 pizzaAmount(slices)입니다

  1. 피자가 없으면 왼쪽 결과는 0입니다
  2. 슬라이스 결과가 하나 뿐인 경우 해당 슬라이스가
  3. 슬라이스가 두 개 이상인 경우 결과는 다음과 같습니다.

(파이썬 구문 사용)

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

다시 말해, 대안을 모두 고려해야하며 슬라이스를 사용한 후에는 재귀 호출의 결과를 제외한 나머지 피자를 모두 얻게됩니다 (친구가 동일한 전략을 사용하기 때문에).

배열은 실제로 고정되어 있으며 첫 번째 및 마지막 슬라이스 인덱스를 매개 변수로 고려할 수 있기 때문에 DP (또는 메모리)로 이것을 구현할 수 있습니다.

원래의 전체 문제를 해결하려면 모든 슬라이스를 시작 슬라이스로 시도하고 결과를 최대화하는 슬라이스를 선택하면됩니다.


감사합니다 "6502". "단지 슬라이스를 고려하고 두 끝 중 하나에서 선택"이라는 힌트를 활용하여 문제를 더 잘 시각화 할 수 있습니다. 주어진 재발 관계는 상대방의 최적의 선택을 돌보고 있습니다. 공식적인 알고리즘을 곧 게시하겠습니다. 고마워요 !!

궁금한 점은이 알고리즘의 복잡성 순서는 무엇입니까? 0 (n * 2 ^ n)?

@Akron : 동적 프로그래밍 방식이나 메모가없는 상태입니다. 그러나 결과 pizzaAmount는 남은 조각의 시작 및 중지 색인에 따라 달라지며 피자 조각을 당신과 친구가 이미 먹은 순서에 의존하지 않으므로 결과를 저장할 수 있다는 사실을 이용할 수 있습니다 재 계산을 피하기위한 행렬. 그러므로 알고리즘의 순서는 O (n ** 2)입니다.
6502

누구든지 여전히 이해하기 위해 고군분투하는 경우이 링크 에는 매우 좋은 설명이 있습니다.
Amit Shekhar

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)(두 번째 사람에게 남은 양)을로 정의하십시오 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) ),

Alice가 먹을 수있는 최대 값은 다음과 같이 계산됩니다.

max( S_i + F(i+1, (i-1) if i > 1 else n) ).
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.