D&C DP (optimizarea divide et impera)
Introducere
Să considerăm o dinamică cu următoarea formulă:
unde este o funcție de cost care poate fi calculată în . De asemenea, pentru .
O implementare simplă ne-ar da o complexitate de dacă și , deci se impune găsirea unei optimizări care să îmbunătățească soluția.
În cele ce urmează, vom prezenta tehnica Divide & Conquer DP, care ne va permite să optimizăm această dinamică la .
Mai întâi, vom defini pentru un oarecare ca fiind valoarea care minimizează expresia din ecuație. Astfel, D&C DP se aplică doar dacă
De multe ori, demonstrația poate fi dificil de găsit, dar dacă funcția de cost respectă quadrangle inequality, condiția se aplică.
Sfat
De multe ori, dacă credeți că problema pe care o rezolvați are o asemenea optimizare în spate, puteți începe prin a scrie o soluție brută, iar dacă se aplică, sunt șanse mari să puteți folosi această optimizare cu destul de mult succes.
Astfel, vom putea aplica ideea din spatele divide et impera. Pentru un interval , știm punctele posibile care pot fi optime . Astfel, vom încerca să calculăm dinamica pentru valoarea din mijloc, iar în funcție de valoarea optimă găsită (o notăm ), vom împărți intervalele recursiv în două, după cum urmează:
- , respectiv
- , respectiv .
Vom continua acest lucru până când ajungem la intervale unitare, caz în care ne vom opri.
Deoarece fiecare valoare a apare de ori, vom avea o complexitate finală de .
Problema exemplu - Subarray Squares
Notă
Această problemă are și o soluție video postată de Algorithms Conquered aici.
Pentru a rezolva această problemă, ne putem gândi mai întâi la o dinamică simplă dar care este prea înceată, în stilul celei descrise mai devreme în articol.
Totuși, se poate observa că proprietatea legată de valorile optime pentru fiecare stare se respectă, ceea ce ne duce cu gândul la aplicarea tehnicii D&C pentru implementarea acestei probleme.
Recomandăm citirea implementării de mai jos, deoarece este una educațională și instructivă și pentru celelalte probleme pe care le veți rezolva folosind această tehnică.
--8 < --"avansat/dc-dp/subarraysquares.cpp"Problema suxumetre
Dinamicele de genul sunt foarte clasice, chiar au o optimizare foarte faină. Pentru un dp cum ar fi , notăm ca fiind "the optimum splitting point" și egal cu -ul care minimizează .
Atunci putem spune că pentru oricare doar dacă oricum am alege patru indici ;
Conform definiției avem și .

În primul rând, vom analiza ce intervale contribuie la costurile din inegalitatea de mai sus. Distingem trei tipuri de intervale:
- interval roșu: inclus în sau , dar nu în .
- interval albastru: inclus în .
- interval verde: inclus în , dar nu în sau .
Vom scrie membrul stâng și membrul drept al inegalității în funcție de cele trei tipuri de intervale:
ceea ce este adevărat din definiția funcției .
Putem deci să dezvoltăm un algoritm tip "divide and conquer", unde vom împărți succesiv vectorul în două intervale și să calculăm dinamica pentru în intervalul .
Complexitatea finală va fi astfel .
--8 < --"avansat/dc-dp/suxumetre.cpp"Concluzii
Această tehnică este una foarte des întâlnită în ceea ce privește optimizările de programarea dinamică, fiind relativ ușor de înțeles după ce ați căpătat suficientă experiență cu celelate tehnici specifice programării dinamice.
Recomandăm și abordarea problemelor de mai jos, precum și a articolelor suplimentare care cuprind multe explicații la problemele suplimentare și nu numai.
Probleme suplimentare
- Infoarena cubeon
- ONI 2006 Petrom
- Codeforces Ciel and Gondolas
- Atcoder Yakiniku Restaurants
- Codeforces Yet Another Minimization Problem
- USACO Platinum Circular Barn
- USACO Platinum Mowing Mischief
- COI 2015 Nafta
- Codeforces Trucks and Cities
- JOI 2013 Bubblesort
- IOI 2014 Holiday
- Codeforces Partition Game