“Pizza toplama problemi” dinamik programlama teknikleri kullanılarak nasıl çözülür?


9

Winkler'ın pizza toplama sorunu:

  • Dilimin alanı nolduğu dairesel bir dilim pizzalı pasta, yani alan her pasta parçası için farklıdır.iS_i
  • Yiyenler Alice ve Bob sırayla dilimleri toplarlar, ancak pastada birden fazla boşluk oluşturmak kaba olur (izin verilmediğini düşünün).
    • Bu nedenle her yiyici, açık bölgeye bitişik iki dilimden birini almakla sınırlıdır. Alice önce gelir ve her iki yiyen de mümkün olduğunca fazla pasta arar.

Hem Alice hem de Bob pizza tüketimini en üst düzeye çıkarmak için mükemmel oynarsa, dinamik bir programlama algoritması Alice'in ne kadar pasta yediğini nasıl belirler?

Benim anlayışım:

Genel bir DP probleminde, özyineleme ağacı kullanılarak veya daha sıkı bir şekilde bir DAG kullanılarak görselleştirilebilen alt problemler bulmaya devam ediyoruz. Burada, alt problemleri bulmak için herhangi bir ipucu bulamıyorum.

Burada, belirli bir S_i s seti için Alice tarafından yenen dilim alanını en üst düzeye çıkarmamız gerekiyor. Bu, (n-1) permütasyonlarından Pizza dilimlerinin permütasyonunun seçilmesine bağlı olacaktır. Alice'in aldığı her n \ 2 dönüşte iki seçenek arasından bir maksimum alan dilimi seçmek, bize bir permütasyon için toplam dilim alanını verecektir. Tüm bu permütasyonlar için dilim alanı bulmamız gerekiyor. Ve sonra bunlardan maksimum.

Biri bana nasıl ilerleyeceğim konusunda yardım edebilir mi?

Yanıtlar:


5

Bir sıraya yeni yerleştirilmiş dilimleri düşünerek başlayın ve iki uçtan birini seçebilirsiniz. Varsayarak Bu durumda o olduğu açıktır seçti sırası sizde pizzaAmount(slices)olduğu

  1. Pizza kalmadıysa sonuç 0 olur
  2. Sadece bir dilim sonucu varsa o dilim
  3. En az iki dilim varsa, sonuç şudur:

(Python sözdizimi kullanarak)

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

diğer bir deyişle, her iki alternatifi de düşünmelisiniz ve diliminizi aldıktan sonra, özyinelemeli çağrı sonucu hariç kalan tüm pizzaları alacaksınız (çünkü arkadaşınız aynı stratejiyi kullanacaktır).

Dizi gerçekten sabit olduğundan ve sadece ilk ve son dilim dizinini parametre olarak değerlendirebileceğiniz için bunu DP (veya notlama) ile uygulayabilirsiniz.

Orijinal tam sorunu çözmek için, tüm dilimleri başlangıç ​​dilimi olarak denemeniz ve sonucu en üst düzeye çıkaranı seçmeniz yeterlidir.


Teşekkürler "6502". "Bir sıraya yerleştirilmiş dilimler göz önünde bulundurularak ve iki uçtan birinden seçilerek" ipucunu kullanarak sorunu daha iyi görselleştirebilirim. Verilen nüksetme ilişkisi, rakibin de en uygun seçimi yapmasıdır. Yakında resmi bir algoritma yayınlayacağım. Teşekkürler beyler!!

Sadece merak ediyorum, bu algoritma için karmaşıklık sırası nedir? 0 (n * 2 ^ n)?

@Akron: Dinamik bir programlama yaklaşımı veya notu olmadan bu olurdu. Bununla birlikte, sonucunun sonucunun pizzaAmountsadece kalan dilimlerin başlangıç ​​ve bitiş indeksine ne bağlı olduğuna ve siz ve arkadaşınızın zaten hangi pizza dilimlerini yediği sırasına bağlı olmadığından yararlanabilirsiniz, böylece sonucu bir yeniden hesaplamayı önlemek için matris. Dolayısıyla algoritmanın sırası O (n ** 2) 'dir.
6502

Birisi hala anlamakta zorlanıyorsa, bu bağlantının çok güzel bir açıklaması var.
Amit Shekhar

3

Pizzanın bir kısmı için, F(i,j)ilk seçen dilimi ne kadar kişi yiyebileceği maksimum olarak tanımlayın . Pizza parçasının dilimleri (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)(İkinci kişi için ne kadar kaldı) olarak tanımlayın sum(S_x, x in slices(i,j)) - F(i,j).

İle:

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

Alice'in yiyebileceği maksimum:

max( S_i + F(i+1, (i-1) if i > 1 else n) ).
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.