Sunteți pe pagina 1din 4

3.

Metoda napoi
Datorit faptului c este una din cele mai complexe tehnici de programare, vom acorda o
atenie mrit acestei modaliti de tratare a programelor, atenie nsoit de un numr mare de
exemple. Ele sunt n majoritate de facturi diferite, i constituie un bun punct de pornire n
formarea unei gndiri dinamice.
Programarea dinamic este o tehnic de programare de nivel nalt n sens c necesit o
mbinare ntre intuiie i rigurozitate matematic.
n general, termenul de "principiul optimalitii" semnific urmtoarele: atunci cnd vrem s
obinem o situaie favorabil dintr-un anumit punct de vedere, este bine ca ea s rezulte tot din
spaii favorabile.
Suma maxim divizibil cu n
Se citete n numr natural i n-numere naturale. Se cere s se tipreasc cea mai
mare sum care se poate forma utiliznd cele n numere naturale (fiecare numr poate
participa o singur dat n calculul sumei) i care se divide cu n precum i numerele care
alctuiesc aceast sum.
De exemplu: pentru n=5; numerele citite: (2,3,4,9,3).
Avem S=15 i numerele care o alctuiesc (2,4,9).
Observaia 1: Aceasta nu este singura sum care se poate forma, de
exemplu S1=5, (2,3). S poate fi format i cu alte numere (3,9,3). Cu
toate acestea soluia data nu ndeplinete condiiile din enun.
Observaia 2: Problema admite ntotdeauna soluie.
n general, avem 2 n submulimi ale unei mulimi cu n elemente (acest numr include i
submulimea vid). Dac am considera toate aceste sume pentru a o alege pe cea care
ndeplinete condiiile cerute de problem, timpul de calcul ar fi foarte mare (O(2 n )).
Vom rezolva problema n n etape. Pentru prima etap (n care lum n consideraie
numai primul numr citit) se poate forma o singur sum. La etapa i se vor calcula sumele
maxime care prin mprirea la n dau resturile (0,1,...,n-1). Dup ultima etap se tiprete
suma care prin mprirea la n d restul 0.
De fapt, n acest mod rezolvm o problem mai general i anume de a tipri
dup etapa n sumele maxime care prin mprirea la n, dau resturile (0,1,...,n-1). Nu pentru
orice numr cuprins ntre 1 i n exist o sum care mprit la n d acest rest.
Exemplu: n=2, numerele citite sunt 4 i 6 iar restul este 1.
Notm cu n1 ,..., nn cele n numere din care se formeaz sumele. Sumele maxime care
mprite la n dau resturile (0,1,...,n-1) se rein n vectorul S.
Astfel, S(0) va reine suma maxim care mprit la n d restul 0, S(1) va
reine suma maxim care mprit la n d restul 1. S(n-1) va reine suma
maxim care mprit la n va da restul n-1. Dac la un moment dat nu exist nici o
sum care mprit la n d restul i, S(i) va retine numrul 0. Rezolvm problema n n pai.
La pasul i se rein sumele maxime care se pot forma cu primele i numere. Pentru a face
distincte ntre diversele valori reinute n vectorul S vom nota S i coninutul vectorului S

dup ce am prelucrat primele i numere. De exemplu, prin S i (k ) nelegem suma maxim


care mprita la n d restul k, sum obinut cu primele i numere naturale.
Dup prelucrarea primului numr vom avea:
n , daca n1 mod n k
S1 ( k ) 1 , k {0,1,...,.n 1}
0, in rest
Semnificaia formulei de mai sus este urmtoarea: cu un singur numr se poate
forma o singur sum, cea egala cu numrul respectiv. Ea va fi memorat n acea
component a vectorului S care are indicele egal cu restul mpririi numrului la n.
ni 1 , daca ni 1 mod n k

S i 1 (k ) maxSi (k )
S ( p) n , daca ( S ( p) n ) mod n k , i {1,2,...,n 1}, k {0,1,...,n 1}
i i 1 i i 1

Semnificaia formulei de mai sus este: vectorul S se actualizeaz pentru ni 1


astfel: fiecare component k a sa va avea ca valoare maximul dintre:
- valoarea ni 1 dac restul mpririi lui ni 1 , la n este k
- vechea valoare
- o alt suma reinut la care dac adunm ni 1 , obinem o valoare care mprit la n d
restul k.
Pentru a demonstra corectitudinea algoritmului vom folosi inducia matematic. La
citirea primului numr nu se poate calcula dect o singur sum care este, evident,
maxim.
Fie S1 , S 2 ,..., S i irul primilor i vectori generai, sumele reinute le presupunem optime.
Modul de calcul al vectorului Si+1 demonstreaz c Si+1 va conine sumele optime calculate
cu ajutorul primelor i+1 numere (nu se pot genera sume cu proprietatea cerut care s fie
mai mari).
Pentru problema dat putem spune ca dac irul S1 , S 2 ,..., S i este optim aceasta nseamn
c este optim ntre 1 i i, ceea ce justific alegerea metodei napoi.
Relum exemplul considerat la nceputul acestui paragraf. Pentru n=5 i citim numerele
2, 3, 4, 9, 3.
Reinem sumele ntr-un vector S care va avea 5 componente cu indici ntre 0 i 4 (dup
valorile resturilor obinute prin mprirea la n a acestor sume).
rest 0 1 2 3 4
s 0 0 0 0 0
Alctuim toate sumele care se pot forma cu primul numr citit.
rest 0 1 2 3 4
s 0 0 0 0 0
stare 2
Prin stare[i] vom nelege mulimea numerelor care alctuiesc o anumit sum. Pentru
fiecare rest n parte, se rein sumele maxime care se pot forma cu 2 i 3.
rest 0 1 2 3 4
s 5 0 0 0 0
stare 2 2 3
3
Algoritmul continu pn la citirea tuturor numerelor.
Programul Pascal este:
Program suma_maxima;
uses crt;
type vector=array[0..255] of integer;
vector1=array[0..255] of set of byte;
var s,s1,numar:vector;n,i,j:integer;
stare,stare1:vector1;
Begin
clrscr;
Write('n=');
readln(n);
for i:=1 to n do
begin
write('Introdu nr ',i,' ');
readln(numar[i]);
stare[i-1]:=[];
s[i-1]:=0;
end;
s[numar[1] mod n]:=numar[1];
stare[numar[1] mod n]:=[1];
for i:=2 to n do
begin
s1:=s;
stare1:=stare;
if s1[numar[i] mod n]<numar[j] then
begin
s[numar[i] mod n]:=numar[i];
stare[numar[i] mod n]:=[i];
end;
for j:=0 to n-1 do
if s1[j]+numar[i]>s[(s1[j]+numar[i]) mod n] then
begin
s[(s1[j]+numar[i]) mod n]:=s1[j]+numar[i];
stare[(s1[j]+numar[i]) mod n]:=stare1[s1[j] mod n]+[i] ;
end;
end;
Writeln('Suma este egala cu',s[0]);
writeln('Numerele ce o formeaza ');
for j:=0 to 255 do
if j in stare[0] then writeln(j,' ',numar[j]);
readkey;
End.

Rezultatul rulrii programului:

S-ar putea să vă placă și