EDIT: Rozwiązanie optymalne (tj. najszybsze) i najbardziej eleganckie oparte jest o programowanie dynamiczne. Wcześniejszy pomysł o drzewo, jak również rozwiązanie kolegi michu niestety jest nieoptymalny i obciążający pamięciowo.
Kod w C wygląda następująco:
#include <stdio.h>
#define CEL 100
#define NOMINALY 7
int main() {
int i, j;
// tablica z wartościami
int t[CEL + 1];
for (i = 0; i <= CEL; i++) { t[i] = 0; }
t[0] = 1;
// tablica z nominałami
int n[] = {1, 2, 5, 10, 20, 50, 100};
// zaczynamy zabawę
for (i = 0; i < NOMINALY; i++) {
for (j = n[i]; j <= CEL; j++) {
t[j] = t[j] + t[j - n[i]];
}
}
printf("%d\n", t[CEL]);
}
Gwoli wytłumaczenia algorytmu:
Wszystko odbywa się w jednej tablicy, jak widać z kodu. O wiele łatwiej jednak rozpisać to sobie na kartce w tablicy. Liczba kolumn w takiej tabeli równa jest liczbie celu, tj. 100. W wierszach tabeli znajdują się kolejne (rosnące) nominały.
W komórkach tabeli znajdą się informacje, na ile sposobów można uzyskać daną kwotę, korzystając z danego i poprzednich nominałów, tj. w komórce (CEL=45, NOMINAŁ=5) znajduje się informacja na ile sposobów możemy osiągnąć sumę 45zł korzystając z nominałów 5, 2 i 1. Widać z tego, że odpowiedź znajdziemy w komórce (CEL=100, NOMINAŁ=10). Kwestią pozostaje wypełnienie tabeli;)
Dorzucamy sobie jeszcze (nie widać tego w kodzie) wirtualne kolumną ("0"), wypełnioną jedynkami, i wirtualny wiersz (też "0") wypełniony zerami.
Tabelę wypełniamy jednak bardzo prosto: dodajemy wiersz wyżej, kolumną o bieżący nominał niższą., czyli komórka (CEL=45, NOMINAŁ=5) będzie równa (CEL=45, nominał = 2) + (CEL=45-5=40, NOMINAŁ=5).
Polecam rozpisanie sobie na kartce i poczytanie o programowaniu dynamicznym.
A, byłbym zapomniał. Wynik to 4563:D
A ja bym to zrobił przez przeszukiwanie w głąb.
Czyli w ten sposób:
- Zacznij od pustej tablicy
- Na początek tablicy wrzuć pierwszy nominał
- Jeżeli suma elementów w tablicy jest mniejsza od 100, dorzuć element mniejszy/równy od ostatniego taki, żeby suma była nie mniejsza niż 100.
- Jeżeli suma elementów jest równa 100, odrzuć ostatni element, na koniec tablicy dorzuć następny element mniejszy od odrzuconego i przejdź do punktu 3.
Trochę jestem już zmulony, ściągnąłem szkła kontaktowa a jeszcze nie mam okularów, więc naprawdę nie mam siły tego implementować:)
Jak będziecie grzeczni, zaimplementuję jutro po południu.