Spartacus
Аутор: Марко Миленковић
Текст и тест примери: Младен Пузић и Марко Миленковић
Анализа решења: Марко Миленковић
Тестирање: Александар Вишњић
N \leq 20
У овом подзадатку је довољно да испробамо свих 2^N могућих подскупова такмичара. За сваки могући подскуп проверићмо да ли је збир њихове контраверзе мањи од K и да ли за сваког такмичара i у том подскупу важи и да је p[i] (осим кад је p[i] = 0) такође у том скупу. Међу свим подскуповима у којима то важи уочимо онај са највећим збирним спартанством и испишемо ту вредност.
p[i] = i-1, за 1 \leq i \leq N
У овом подзадатку је јасно да ћемо моћи да изаберемо само првих неколико такмичара, да бисмо испунили услов затворености (ако изаберемо i, морамо да изаберемо и p[i]). Тако да је решење да сабирамо спартанства почев од првог такмичара докле год је њихова укупна контраверза мања од K. На крају испишемо збирно спартанство.
Сваки такмичар има различитог такмичара који би се јавио на њихову дисквалификацију
У овом подзадатку је кључно да такмичаре посматрамо као чворове у усмереном графу, а усмерена грана постоји између чворова i и p[i] за 1 \leq i \leq N. Како је p[1], p[2], \ldots, p[N] пермутација бројева 1,2,\ldots,N, закључујемо заправо да ће формиран граф бити унија неколико циклуса. Главна идеја, која ће служити и за наредне подзадатке, јесте да ако изаберемо једног такмичара из циклуса, онда морамо да их изаберемо све (јер ће се циклично јављати). Стога, потребно је уочити све циклусе и сваки циклус “компресовати” у по један чвор (један циклус такмичара можемо посматрати као једног такмичара чија су контраверза и спартанство једнаки збиру свих такмиара из циклуса). Сада задатак решавамо као познат проблем ранца.
Не постоји такмичар који би се поново јавио да је спартак након што је дисквалификован
Овај подзадатак је у неку руку супротан претходном, јер можемо закључити да нећемо имати циклусе. Сада имамо усмерено стабло и задатак решавамо динамичким програмирањем над стаблом. Нека је dp[i][j] решење за подстабло чвора i, уколико је збирна контраверза у подстаблу j. Прелаз ће нам затим бити $$dp[i][j + k[i]] = max(dp[i][j+k[i]], dp[i][j + k[i] - l] + dp[y][l])$$, где су y сва деца чвора i, а l вредност коју итерирамо од 0 до j. Почетно стање нам је наравно dp[i][k[i]] = s[i].
Решење без додатних ограничења
У овом подзадатку уклапамо идеје из претходна два. Потребно је да уочимо све циклусе и компресујемо их у један чвор, што нпр. можемо урадити Тарџановим алгоритмом. Затим примењујемо динамичко програмирање из претходнох подзатка.