КАКВО СА ТЕ?
• В комбинаторната математика каталaнските числа са
поредица от естествени числа, които се срещат в
различни проблеми с броенето, често включващи
рекурсивно дефинирани обекти. Те са кръстени на
френско-белгийския математик Йожен Шарл Каталан
(1814–1894).
ФОРМУЛА
• Cn = (2 * n)! / ((n + 1)! * n!)
• Първите числа на Каталан за n = 0, 1, 2, 3 … са:
1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58785, ...
АПЛИКАЦИЯ В КОМБИНАТОРИКА
• В комбинаториката има много проблеми с броенето,
чието решение се дава от числата на Каталан. Книгата
Enumerative Combinatorics: Volume 2 от
комбинаторика Richard P. Stanley съдържа набор от
упражнения, които описват 66 различни
интерпретации на числата на Каталан. Следват някои
примери с илюстрации на случая C3 = 5
DYCK WORDS
• Cn е броят на думите на Dyck с дължина 2n. Думата
на Dyck е низ, състоящ се от n X и n Y, така че нито
един начален сегмент от низа няма повече X от Y.
Пример за думите на Dyck с дължина 6:
XXXYYY XYXXYY XYXYXY XXYYXY XXYXYY
• Ако заместим X с отварящи скоби, а Y със затварящи,
виждаме, че скобите си съвпадат:
((())) ()(()) ()()() (())() (()())
ЗАВЪРШЕНИ СКОБИ
• Cn е броят на различните начини, по които n + 1
фактора могат да бъдат напълно поставени в скоби. За
n = 3, например, имаме следните пет различни
поставяния в скоби на четири фактора:
((ab)c)d (a(bc))d (ab)(cd) a((bc)d) a(b(cd))
ПЪЛНИ ДВОИЧНИ ДЪРВЕТА
• Чрез каталанските числа може да покажем броят на
пълните двоични дървета с n + 1 листа или,
еквивалентно, с общо n вътрешни възли:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class CatalanNumbers {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = Integer.parseInt(scanner.nextLine());
List<Long> catalanNumbers = getCatalanNumbers(new ArrayList<>(List.of(1L)), n);
System.out.println(catalanNumbers);
}
public static List<Long> getCatalanNumbers(List<Long> catalanNumbers, int n) {
if(catalanNumbers.size() == (n + 1)) {
return catalanNumbers;
}
long currentCatalanNumber = factorial(2 * catalanNumbers.size()) /
(factorial(catalanNumbers.size() + 1) * factorial(catalanNumbers.size()));
catalanNumbers.add(currentCatalanNumber);
return getCatalanNumbers(catalanNumbers, n);
}
public static long factorial(int num) {
if(num == 0) {
return 1;
} else {
return num * factorial(num - 1);
}
}
}
ПРИМЕРЕН КОД С РЕКУРСИЯ