110 likes | 245 Views
Projekt JPAZ2/2008. Marek Daňko. Obsah. Popis problému NáÄrt rieÅ¡enia Vyhodnotenie algoritmu. Ekonómova odmena. Dlhoprst sa pustil do hry s pirátmi v ktorej nejde už len o zbohatnutie ale aj o jeho život.
E N D
Projekt JPAZ2/2008 Marek Daňko
Obsah • Popis problému • Náčrt riešenia • Vyhodnotenie algoritmu
Ekonómova odmena • Dlhoprst sa pustil do hry s pirátmi v ktorej nejde už len o zbohatnutie ale aj o jeho život. • P pirátov si nevie podeliť lup, ktorí pozostáva z S mincí, pričom sa už dohodli na takýchto pravidlách: • Piráti sa očíslujú, čiže každý dostane číslo od 1 po P • Pirát s číslom P navrhne rozdelenie lupu a ostatný piráti hlasujú, ak je aspoň polovica za návrh je prijatý, ak nie piráta zastrelia. • Každý pirát sa pri hlasovaní riadi len troma pravidlami: • Ak by pirát v budúcnosti určite zomrel hlasuje za(bez ohľadu na obnos, ktorí získa). • Každý pirát chce zarobiť čo najviac, čiže ak má niekedy v budúcnosti šancu zarobiť viac mincí hlasuje proti(ale len ak by prežil). • Každý z pirátov chce zabiť čo najviac pirátov. Každý pirát vie že aj ostatný piráti sa riadia tými istými pravidlami.
Dlhoprst ponúkol pirátom, že ich očísluje za podmienky, že môže hrať aj on z poradovým číslom P+1.Program dostane na vstup S = počet mincí a P = počet pirátov . Je potrebné zistiť či Dlhoprst môže vôbec prežiť, ak áno tak treba navrhnúť rozdelenie mincí medzi pirátov tak aby bol Dlhoprstov zisk čo najväčší .Príklad: Pre S=100 a P=2 Dlhoprst prežiť môže a jeho zisk je 100 mincí. Jeho návrh je dať obom pirátom nula mincí. Pirát číslo 2 pre jeho návrh hlasuje, pretože inak (keby bol Dlhoprst zastrelený) by pirát 1 hlasoval proti ľubovolnému jeho návrhu a on sám by bol zastrelený.
Náčrt riešenia • Najprv budeme uvažovať, že S je dostatočne veľké. • Prvé pozorovanie je, že ak P<>1 tak Dlhoprst určite prežije. • Pozrime sa ako bude vyzerať rozdelenie pre malé P: P 0 S 1 S -1 2 0 0 S 3 1 1 0 S-2 4 0 2 1 0 S-3 alebo 4 2 0 1 0 S-3 5 0 2 2 1 0 S-5 alebo 5 2 0 2 1 0 S-5 alebo 5 2 2 0 1 0 S-5 (posledná cifra je Dlhoprstov zisk , -1 = † )
Dôležité je to, prečo pirátom 1,2 stačia v prípade P=5 len 2 mince. Vzhľadom na to, že situácia môže v prípade P=4 dopadnúť dvoma spôsobmi (buď dostane zaplatené 1. nebo 2. pirát), nemajú títo piráti istotu, že tie 2 mince získajú. Preto sa pri P=5 uspokoja s dvoma mincami (avšak jedna by im nestačila - majú nádej na dve). • Ak budeme pokračovať v rozbore ďalej, zistíme, že okrem počiatočných prípadov (P <= 3) je optimálne riešenie takéto: chceme, aby pre Dlhoprsta hlasovalo ceil(P/2) pirátov. Pirátovi P nedáme nič, pirátovi P-1 dáme 1 mincu a z ostatných pirátov 1…P-2 vyberieme ľubovolných ceil(P/2)-1 a dáme každému z nich 2 mince (pre jednoduchosť vyberieme napr. prvých ceil(P/2)-1 pirátov). Celkom použijeme 2(ceil(P/2)-1)+1 = 2ceil(P/2)-1 mincí. • Ak je teda S >= 2ceil(P/2)-1, vieme úlohu vyriešiť dokonca v konštantnom čase a priestore. Prípad P <= 3 vyriešime tabuľkou a pre ostatné hodnoty P použijeme popísané rozdelenie (pozor na to, že nesmieme vypísať počet mincí pre každého piráta – to by malo zložitosť O(P)).
Situácia začne byť zložitejšie, ak je S menšie ako 2ceil(P/2)-1.Nie je totiž pravda, že potom nikdy neexistuje riešenie. Napr. : S=1 P 0 1 1 1 -1 2 0 0 1 3 0 0 1 -1 4 0 1 0 0 0 5 0 1 0 0 0 -1 6 0 1 0 0 0 -1 -1 7 0 1 0 0 0 -1 -1 -1 8 0 1 0 0 0 0 0 0 0 Aj keď sa piráti delia o jedinú mincu, ak je ich 8, Dlhoprst môže prežiť. Využije to, že pre neho zadarmo budú hlasovať piráti 6,7,8 ktorí inak zomrú.
Riešenie situácie, keď je S malé, založíme na dynamickom programovaní. Budeme postupne riešiť situáciu pre rastúce P až do zadaného. U každého piráta si budeme pamätať, aký počet mincí má "istý" a či má šancu získať viac než svoju "istotu". • Povedzme, že poznáme riešenie pre P-1 pirátov a zaujíma nás riešenie situácie s P pirátmi. Hľadáme ceil(P/2) pirátov, ktorým zaplatíme najmenej. Ak budeme chcieť, aby pre Dlhoprsta hlasovali všetci piráti, ktorí majú istých R mincí, ponúkneme im R+1 mincí a upravíme ich "istotu". Ak budeme chcieť, aby hlasovali len niektorí piráti z tých s "istotou" R mincí, ponúkneme im taktiež R+1 mincí. Avšak nezmeníme ich "istotu", len si u nich poznamenáme, že majú šancu získať viac než svoju "istotu".
Pozorovanie: žiadny pirát (okrem toho, ktorý práve navrhuje rozdelenie) nemôže dostať viac než dve mince, pretože "istota" každého piráta je menšia než dve • Pokiaľ teda zisťujeme riešenie situácie s P pirátmi zo situácie s P-1 pirátmi, najprv zistíme, ktorým pirátom bude Dlhoprst platiť. Vzhľadom k tomu, že "istoty" všetkých pirátov sú menšie než dva, dokážeme to v konštantnom čase (pokiaľ si pamätáme, koľko pirátov má "istotu" rovnú -1 (smrť), koľko ju má nulovú a koľko pirátov má istú 1 mincu). Potom môžeme jedným priechodom nad pirátmi 1…P upraviť ich "istoty" a šance na získanie väčšieho počtu mincí. To celé zvládneme v čase O(P).
Celý algoritmus bude fungovať tak, že bude zisťovať, jak dopadnú návrhy pre 1,2,…,P pirátov a poslední z týchto návrhov vypíše. Pri výpise všetkých pirátov, ktorí nemajú šancu na nič viac než ich "istotu", zaplatíme. Avšak pirátom, ktorí majú nádej na viac, platíme o jednu mincu viac a nemusíme im platiť všetkým, len toľkým, aby sme podplatili celkom ceil(P/2) pirátov.
Vyhodnotenie algoritmu • Celkom P-krát opakujeme postup so zložitosťou O(P) a potom výsledky v čase O(P) vypíšeme, čiže celková časová zložitosť popísaného algoritmu je O(P2). Pamäťová zložitosť je O(P). A aj keď popísaný algoritmus používame len v prípade, keď S < 2ceil(P/2)-1, funguje korektne pre všetky S.