Anyways inapoi la treaba serioasa. Backtracking. Care e ideea? Ai un vector de valori posibile, sa ii zicem pos[], si o stiva st[] in care bagam toate permutarile intre o parte din elementele din pos (sau toate, dupa caz) si verificam daca solutia este corecta.
Varianta recursiva e cea mai scurta si dragalasa:
void bkt(int p) { for (int i=0;i < n_pos;i++) { st[p]=pos[i]; if(p==nr_cautat) if (verif(p)) afis(p); else bkt(p+1); } }
THE END. Astea sunt cele 5 randuri pt care trebuie sa intelegeti principiul.
Ca exemplu de rulare, sa zicem ca avem pos[]={1,2,3} si nr_cautat =2. Practic adauga in stiva 1, si apeleaza bkt pentru a 2a pozitie din stiva. Va baga in stiva {1, 1} si verifica daca solutia este corecta. Dupa, vom avea in stiva {1, 2} si verifica. Dupa, {1,3}. {2, 1} etc. Functia verif() depinde de problema, evident. O idee ar fi sa salvam in st[] doar indicii pentru pos[], adica st[p]=i; ca sa verificam mai usor in verif(p) daca elementele sunt distincte. Alteori, e mai eficient sa facem verificarea imediat cum adaugam un element nou, si dupa sa vedem daca am ajuns la numarul de elemente cautat.
Asta este principiul de baza. In rest, conteaza creativitatea programatorului pentru a-l optimiza. Dar, desigur, ppl like telling you how to think, asa ca avem un fel de grade de optimizare, AC1, AC2, blabla. Voi scrie intr-un post urmator cu ce se mananca fiecare.
Lol frate, e scris azi si e totusi pe gogule :)
RăspundețiȘtergere