* При метода търсене с връщане процесът на решаване на задачата може да се представи като дърво на търсенето.
* Движението по дървото е от корена към листата (търсене) и
когато се достигне листо (няма възможен ход и не е достигнато
решението), движението се обръща от листото към корена (връщане).
* Идеята на метода на разклоненията и границите е връщането да
започне преди да е достигнато листо, т.е. във вътрешен възел, ако
сме сигурни, че решението не е в необходеното поддърво.
Даден е квадрат, състоящ се от 7x7 квадрати. Да се пресметне по
колко начина може да се стигне от горния ляв квадрат до долния
десен квадрат с хоризонтално и вертикално движение.
Намиране на всички подмножества на едно множество.
{A, B, C}, 2^3 = 8
{}, {A}, {B}, {C}, {A,B}, {A,C}, {B,C}, {A,B,C}
Дадено е множество от цели числа. Да се намерят сумите от
елементите на всички подмножества.
subsets.cpp
Задача 12. Суми2021 [Meet in
the middle, AL p. 54]
Дадена е редица от цели числа. Да се провери дали дадено число
може да се получи като сума на числа от редицата.
* Принципи на "разделяй и владей": разбиване на изходната задача на няколко подзадачи (разделяй), решаване на подзадачите и конструиране на решение на изходната задача (владей).
* Двоично търсене.
* Бързо сортиране с
разделяне на дялове (Хоор, "разделяй и владей") - O(n2)
в най-лошия случай, O(n) в най-добрия случай,
O(n log n) средно. Сложността зависи
от избора на елемент за разделяне на дялове.
*
Сортиране чрез сливане
Нека
е дадено n-елементно мултимножество (множество, в
което се допуска повторение на елементи). Ще казваме, че
даден елемент на множеството е негов мажорант, ако се среща
строго повече от n/2 пъти.
Решение
с двоен цикъл: броене колко пъти се среща всеки елемент - O(n2).
Решение
със сортиране при линейна наредба на елементите му:
сортираме и проверяваме средния елемент за мажорант - време
O(n log n) или по-добро, ако сортираме
с по-бърз алгоритъм.
Решение
с броене: O(n + k), ако в масива има
k различни стойности.
Твърдение.
Ако масивът има мажорант и премахнем два различни елемента,
мажорантът на новия масив ще съвпада с този на изходния.
Решение
с кандидат и брояч:
- Ако броячът е 0, кандидат става текущият елемент, а
броячът става 1.
- Ако броячът е различен от 0:
-- Ако кандидатът съвпада с текущия елемент, броячът
се увеличава с 1.
-- Ако са различни, броячът се намалява с 1.
Ако брoячът е 0 - няма мажорант, иначе проверяваме дали
кандидатът е мажорант.
Пример:
C е мажорант
A A A C C B B C C C B C C
А(А,1),
А(А,2), А(А,3), C(А,2), C(А,1), B(?,0), B(B,1), C(?,0),
C(C,1), C(C,2), B(C,1), C(C,2), C(C,3)
C не
е мажорант
A A A A C B B C C C B C C
А(А,1), А(А,2), А(А,3), A(A,4), C(A,3), C(A,2), B(A,1), B(?,0), C(C,1), C(C,2) C(C,3), B(C,2), C(C,3), C(C,4)
* Класическият алгоритъм за умножение на цели числа има сложност O(n2).
* Алгоритъм за умножение на две n-цифрени числа X и Y, като n е степен на 2.
* Тази формула изисква 3 умножения, 6 събирания и 2 премествания вляво (умножения на степени на 2). От рекурентната формула
* Пример 1: 15 x 8 =
120, X = 15 = 11112,
Y = 8 = 10002, n
= 4 = 22
A = 11, B = 11, C = 10, D =
00
AC = 110, (A
- B)(D - C) = 0.10 = 0, BD = 0
XY = 110 << 4 + 110
<< 2 = 1100000 + 11000 = 11110002 =
8+16+32+64 = 12010
* Когато числата са с различен брой цифри и/или този брой не е степен на 2, допълваме отляво с незначещи нули и използваме горния алгоритъм.
* Пример 2. 50 x 25 = 1250, X
= 50 = 1100102, Y = 25 = 110012, n = 8 = 24
с допълване до най-близката степен на 2.
A = 0011 (3), B = 0010 (2), C =
0001 (1), D = 1001 (9)
AC = 0011 (3), (A
- B)(D - C) = 0001.1000 = 1000 (8), BD = 10010
(18)
XY = 3.256 + (8 + 3 + 18).16
+ 18 =
11
<<
8
+
11101
<<
4
= 11 0000 0000 + 1 1101 0000 + 10010 = 100111000102
=
2+32+64+128+1024 = 125010
* Подзадачи:
- представяне на дълги числа (низ или вътрешно);
- брой на битовете на цяло число;
- разделяне на десните от левите битове на числото;
- сума и разлика на две числа.