गतिशील प्रोग्रामिंग तकनीकों का उपयोग करके "पिज्जा लेने की समस्या" को कैसे हल किया जाता है?


9

विंकलर की पिज्जा लेने की समस्या:

  • nस्लाइस का एक गोलाकार पिज्जा पाई , जहां स्लाइस iका क्षेत्र होता है S_iयानी प्रत्येक पाई के लिए क्षेत्र अलग होता है।
  • एलिस और बॉब लेने वाले स्लाइस उठाते हैं, लेकिन पाई में कई अंतराल बनाने के लिए यह असभ्य है (इसे अनुमति न दें)।
    • इस प्रकार प्रत्येक भक्षक खुले क्षेत्र से सटे दो स्लाइसों में से एक को लेने के लिए प्रतिबंधित है। एलिस पहले जाती है, और दोनों खाने वाले ज्यादा से ज्यादा पाई मांगते हैं।

यदि एक ऐलिस और बॉब दोनों अपने पिज्जा की खपत को अधिकतम करने के लिए पूरी तरह से खेलते हैं, तो एक गतिशील प्रोग्रामिंग एल्गोरिदम यह निर्धारित करेगा कि ऐलिस कितना पाई खाती है?

मेरी समझ:

एक सामान्य डीपी समस्या में, हम उप-समस्याओं को खोजने के साथ आगे बढ़ते हैं, जिन्हें पुनरावृत्ति वृक्ष का उपयोग करके या अधिक कसकर, डीएजी का उपयोग करके कल्पना की जा सकती है। यहाँ, मुझे यहाँ उप-समस्याओं को खोजने के लिए कोई नेतृत्व नहीं मिल रहा है।

यहाँ, S_i s के दिए गए सेट के लिए, हमें ऐलिस द्वारा खाए गए स्लाइस के क्षेत्र को अधिकतम करना होगा। यह (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]))

दूसरे शब्दों में, आपको दोनों विकल्पों पर विचार करना चाहिए और यह कि आपके स्लाइस लेने के बाद आपको पुनरावर्ती कॉल के परिणाम को छोड़कर शेष सभी पिज्जा मिल जाएंगे (क्योंकि आपका दोस्त एक ही रणनीति का उपयोग करेगा)।

आप इसे डीपी (या याद रखना) के साथ लागू कर सकते हैं क्योंकि सरणी वास्तव में तय हो गई है और आप केवल पहले और अंतिम स्लाइस इंडेक्स के मापदंडों के रूप में विचार कर सकते हैं।

मूल पूर्ण समस्या को हल करने के लिए आपको स्लाइस शुरू करने के रूप में सभी स्लाइस की कोशिश करने की आवश्यकता है और एक को चुना जो परिणाम को अधिकतम करता है।


धन्यवाद "6502"। मैं "केवल एक पंक्ति पर रखे स्लाइस पर विचार करने और दो छोरों में से एक से उठाकर" के संकेत का उपयोग करके समस्या को बेहतर ढंग से देख सकता हूं। यह देखते हुए कि पुनरावर्तन संबंध प्रतिद्वंद्वी द्वारा इष्टतम विकल्प का ख्याल रख रहा है, साथ ही साथ। मैं जल्द ही एक औपचारिक एल्गोरिथ्म पोस्ट करूंगा। धन्यवाद दोस्तों!!

बस जिज्ञासु, इस एल्गोरिथ्म के लिए जटिलता का क्रम क्या है? 0 (n * 2 ^ n)?

@ एक्रॉन: यह वह है जो यह एक गतिशील प्रोग्रामिंग दृष्टिकोण या संस्मरण के बिना होगा। हालाँकि आप इस तथ्य का लाभ उठा सकते हैं कि इसका परिणाम pizzaAmountकेवल इस बात पर निर्भर करता है कि शेष स्लाइस की शुरुआत और स्टॉप इंडेक्स क्या हैं और न कि किस क्रम पर पिज्जा स्लाइस आप और आपके दोस्त ने पहले ही खा लिया ताकि आप रिजल्ट को स्टोर कर सकें पुनर्संयोजन से बचने के लिए मैट्रिक्स। एल्गोरिथ्म का क्रम इसलिए हे (n ** 2)।
6502

यदि कोई अभी भी समझने के लिए संघर्ष कर रहा है, तो इस लिंक की बहुत अच्छी व्याख्या है।
अमित शेखर

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) ),

अधिकतम जो एलिस खा सकता है, उसकी गणना इस प्रकार की जाती है:

max( S_i + F(i+1, (i-1) if i > 1 else n) ).
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.