Popovici Daniel Gabriel LICEUL TEORETIC DUNAREA CLASA A XI A D PROFESOR INDRUMATOR: BIBICU DORIN
Problema plii unei sume s utiliznd m tipuri de monede Se dau suma s si m tipuri de monede avnd valorile a1, a2, ..., am lei. Se cer toate modalitile de plat a sumei s utiliznd aceste monede. Va trebui s se genereze toi vectorii de forma X=(x1,...xm), care verific relaia: x 1 a 1 +x 2 a 2 +...+x m a m =S
Din aceast relaie se poate vedea c: x 1 poate lua valori ntre 0 i n 1 = x 2 poate lua valori ntre 0 i n 2 = ...................................................... x k poate lua valori ntre 0 i n k = ....................................................... x m poate lua valori ntre 0 i n m =
Trebuie s se determine elementele mulimii: {x1,,xm}| xk{0,,m} unde k=1,,m i x 1 a 1 +x 2 a 2 +...+x m a m =S
Exemplu: S=3; m=2, a[1]=1, a[2]=2. Programul va genera soluiile: (1,1) ce corespunde la 1a1+1a2=11+12=3 (3,0) ce corespunde la 3a1+0a2=31+02=3
0 1 n m
0 1 n m-1
0 1 n 2
0 1 n 1
1 m k x k n k Programul #include<iostream.h> typedef int sir[100]; sir x,n,a; int m,i,k,S,as,ev;
void succ(sir x, int k, int &as) { if(x[k]<n[k]) { as=1; x[k]=x[k]+1; } else as=0; } void valid(int &ev) { ev =1; }
ENUNT: Avand la dispozitie n saculeti cu monede S1, S2, .... Sn, fiecare saculet Si continand Nri monede de valoare Vi sa se afiseze toate modalitatil de a plati o suma data S folosind numai monezi din saculeti.
EXEMPLU: Pentru n=3 , Nr=(10,2,5), V=(1,2,5) si S=5 programul va genera 5 * 1 leu 3 * 1 leu + 1 * 2 lei 1 * 1 leu + 2 * 2 lei 1 * 5 lei
SOLUTIE:
Solutia x[1]......x[n]. Elementul x[i] va avea ca valoare numarul de monede care s-au folosit din saculetul i x[k] poate avea ca valoare orice valoare din intervalul [0,Nrk]. Valid daca k<n --> suma platita pana la acel moment sa nu depaseasca S daca k=n --> suma platita sa fie egala cu S
PROGRAM C++: #include <iostream> using namespace std;
int Valid5(int k) { sum[k]=sum[k-1]+val[k]*x5[k]; if (sum[k]>S) return 0; if (k==n5 && sum[k]!=S) return 0; return 1; } void Afisare5() { int i,j; cout<<sp5; for(i=1;i<=n5;i++) if (x5[i]!=0) cout<<x5[i]<<"*"<<val[i]<<" lei + "; cout<<endl; nrsol5++; }
void Back5() { int k=1, cand; x5[1]=-1; while (k>0) { cand=0; while (cand==0 && x5[k]<nr[k]) { x5[k]++; cand=Valid5(k); } if (cand==0) k--; else if (k==n5) Afisare5(); else {k=k+1; x5[k]=-1;} } } int main() { int i; cout<<endl<<endl<<sp5<<"Plata unei sume de bani"<<endl; cout<<endl<<sp5<<" Numarul tipuri monezi: "; cin>>n5; cout<<sp5<<" Dati suma de plata: "; cin>>S; cout<<endl; for (i=1;i<=n5;i++) { cout<<sp5<<" Valoare moneda tip "<<i<<": "; cin>>val[i]; cout<<sp5<<" Numar monezi tip "<<i<<" : "; cin>>nr[i]; } cout<<endl<<"Solutiile sunt: "<<endl; Back5(); cout<<endl<<sp5<<"Numar solutii: "<<nrsol5; return 0; }
Concluzie Problemele de acest gen nu sunt foarte grele. Deoarece le-am inteles mai mult decat alte genuri. Plata unei sume S este cea mai potrivita pentru mine pentru a lua o nota buna!
Bibliografie Caietul de Informatica de clasa http://lectiiback.blogspot.ro/2010/02/pl ata-unei-sume-utilizand-n-tipuri- de.html https://sites.google.com/site/atestat20 13lmk/probleme-rezolvate/plata-unei- sume-de-bani