- •1) Форд-Беллман
- •2) Флойд-Уоршелл
- •5) Алгоритм поиска компонент связности в графе
- •6) Поиск мостов
- •7) Поиск точек сочленения
- •8)Дейкстра
- •9) Эратосфен
- •10) Задача о назначениях
- •12)Эйлер
- •13) Binpow
- •14) Расширенный Евклид
- •15)Длинка
- •11) Алгоритм Куна нахождения наибольшего паросочетания в двудольном графе
- •16) Диофантовы уравнения
- •17) Нахождение степени делителя факториала
- •18) Дискретное логарифмирование
- •19) Нахождение площади простого многоугольника
- •20) Теорема Пика.
- •21) Пересечение окружности и прямой
- •22) Поиск общих касательных к двум окружностям
- •24) Префикс-функция. Алгоритм Кнута-Морриса-Пратта
- •25) Нахождение всех подпалиндромов
- •26) Максимальный подпалиндром
- •27) Нахождение наидлиннейшей возрастающей подпоследовательности
- •28) Динамика по профилю. Задача "паркет"
- •29) Нахождение наибольшей нулевой подматрицы
- •30) Гаусс
- •31) Интеграл по формуле Симпсона
- •32) Биномиальные коэффициенты
- •33) Числа Каталана
- •34) Ожерелья
- •35)Задача о ферзях
- •36)Ханойские башни
- •37) Правильные скобочные последовательности
- •38) Принцип включений-исключений
- •39) Теория Шпрага-Гранди. Ним
- •40) Оптимальный выбор заданий при известных временах завершения и длительностях выполнения
- •41) Игра Пятнашки: существование решения
- •42) Минимальное остовное дерево. Алгоритм Крускала
- •43) Количество всех остовов графа
- •44) Гамильтонов цикл
- •45) Задача о домино
- •46) Проверка на ацикличность и нахождение цикла
- •47) Топологическая сортировка
34) Ожерелья
Задача "ожерелья" — это одна из классических комбинаторных задач. Требуется посчитать количество различных ожерелий из бусинок, каждая из которых может быть покрашена в один из цветов. При сравнении двух ожерелий их можно поворачивать, но не переворачивать (т.е. разрешается сделать циклический сдвиг).
Решение
Решить эту задачу можно, используя лемму Бернсайда и теорему Пойа. [ Ниже идёт копия текста из этой статьи ]
В этой задаче мы можем сразу найти группу инвариантных перестановок. Очевидно, она будет состоять из перестановок:
Найдём
явную формулу для вычисления
.
Во-первых, заметим, что перестановки
имеют такой вид, что в
-ой
перестановке на
-ой
позиции стоит
(взятое
по модулю
,
если оно больше
).
Если мы будем рассматривать циклическую
структуру
-ой
перестановки, то увидим, что единица
переходит в
,
переходит
в
,
—
в
,
и т.д., пока не придём в число
;
для остальных элементов выполняются
похожие утверждения. Отсюда можно
понять, что все циклы имеют одинаковую
длину, равную
,
т.е.
("gcd"
— наибольший общий делитель, "lcm"
— наименьшее общее кратное). Тогда
количество циклов в
-ой
перестановке будет равно просто
.
Подставляя найденные значения в теорему Пойа, получаем решение:
Можно
оставить формулу в таком виде, а можно
её свернуть ещё больше. Перейдём от
суммы по всем
к
сумме только по делителям
.
Действительно, в нашей сумме будет много
одинаковых слагаемых: если
не
является делителем
,
то таковой делитель найдётся после
вычисления
.
Следовательно, для каждого делителя
его
слагаемое
учтётся
несколько раз, т.е. сумму можно представить
в таком виде:
где
—
это количество таких чисел
,
что
.
Найдём явное выражение для этого
количества. Любое такое число
имеет
вид:
,
где
(иначе
было бы
).
Вспоминая функцию
Эйлера, мы находим, что
количество таких
—
это величина функции Эйлера
.
Таким образом,
,
и окончательно получаем формулу:
35)Задача о ферзях
int SIZE = 0;
int board[13][13];
int results_count = 0;
void showBoard()
{
for(int a = 0; a < SIZE; ++a)
{
for(int b = 0; b < SIZE; ++b)
{
std::cout << ((board[a][b]) ? "Q " : ". ");
}
std::cout << '\n';
}
}
bool tryQueen(int a, int b)
{
for(int i = 0; i < a; ++i)
{
if(board[i][b])
{
return false;
}
}
for(int i = 1; i <= a && b-i >= 0; ++i)
{
if(board[a-i][b-i])
{
return false;
}
}
for(int i = 1; i <= a && b+i < SIZE; i++)
{
if(board[a-i][b+i])
{
return false;
}
}
return true;
}
void setQueen(int a) {
if(a == SIZE)
{
results_count++;
return;
}
for(int i = 0; i < SIZE; ++i)
{ if(tryQueen(a, i))
{
board[a][i] = 1;
setQueen(a+1);
board[a][i] = 0;
}
}
return;
}
int main()
{
std::cin >> SIZE;
setQueen(0);
std::cout << results_count << std::endl;
return 0;
}
