Скачать презентацию Графы динамика рекурсия Рассматриваются задачи из практически не Скачать презентацию Графы динамика рекурсия Рассматриваются задачи из практически не

ЕГЭ_Динамика,Графы,Рекурсия.pptx

  • Количество слайдов: 50

Графы, динамика, рекурсия Рассматриваются задачи из практически не связанных между собой тем. Их названия Графы, динамика, рекурсия Рассматриваются задачи из практически не связанных между собой тем. Их названия приведены в заголовке Авторы : Тагиров Р. Р. , Хадиев Р. М.

Предварительные замечания • 1. Во многих задачах будут серии вычислений. Нужно очень аккуратно их Предварительные замечания • 1. Во многих задачах будут серии вычислений. Нужно очень аккуратно их выполнять и перепроверять ответы. Из-за ошибки на промежуточном этапе можно получить не правильный ответ в конце. • 2. Во время разбора проверяйте результаты моих вычислений – я тоже могу ошибаться. Если обнаружите ошибку – кричите или шлите мне сообщения. • 3. В тех решениях, где будут присутствовать схемы или картинки, масштаб в них не будет соблюдаться или будет соблюдаться очень условно. Рекомендую эти картинки перерисовать к себе в тетрадки – не экономить место на листе, рисовать большие картинки. Иногда мы будем в них добавлять какие-то новые элементы или числа.

Пример графа В этом примере вершины обозначены числами 1, 2, 3 и проведены два Пример графа В этом примере вершины обозначены числами 1, 2, 3 и проведены два ребра: 1 -3 и 2 -3

Раздел 1. Графы • Граф – это множество вершин, некоторые из которых соединены рёбрами. Раздел 1. Графы • Граф – это множество вершин, некоторые из которых соединены рёбрами. • Из названия видно, что графы удобно изображать в виде схемы, чертежа, картинки. Тогда вершины изображают точками, а рёбра – отрезками прямых. Эти рёбра служат для передвижения от одних вершин к другим. • Вершины иногда нумеруют или обозначают буквами, а рёбра могут иметь длины (или другие характеристики). • Самые традиционные задачи с использованием графов – это поиск пути между заданными вершинами или поиск кратчайшего пути.

Дополнительные свойства графов • Если рёбра имеют направления, то они изображаются стрелками и по Дополнительные свойства графов • Если рёбра имеют направления, то они изображаются стрелками и по таким рёбрам можно двигаться только в указанном направлении. Сам граф тогда называют ориентированным. • Если все рёбра позволяют двигаться в обоих направлениях, то такой граф называют неориентированным. • В наших задачах будут встречаться оба типа графов.

Задача 1. Между населёнными пунктами A, B, C, D, E, F построены дороги, протяжённость Задача 1. Между населёнными пунктами A, B, C, D, E, F построены дороги, протяжённость которых указана в таблице. (Отсутствие числа в таблице означает, что прямой дороги между пунктами нет. ) X A B C D E F A X 3 5 B X 1 4 1 C 1 X 3 D 3 X 3 E 5 4 3 X 1 F 1 1 X Определите длину кратчайшего пути между пунктами A и C (при условии, что передвигаться можно только по построенным дорогам).

Решение • В задачах такого рода бывает удобно представить условие в виде картинки – Решение • В задачах такого рода бывает удобно представить условие в виде картинки – графа или схемы дорог. • Длины дорог здесь не приведены, чтобы не загромождать рисунок

 • Нам надо найти кратчайший путь между вершинами А и С, поэтому давайте • Нам надо найти кратчайший путь между вершинами А и С, поэтому давайте «растащим» граф в стороны, ухватив за эти 2 вершины: • Некоторые вершины при этом изменили своё относительное положение, но сам граф при этом не «пострадал» , т. к. соединённые вершины так и остались соединёнными и наоборот!

 • Теперь легко заметить, что все пути из А в С проходят через • Теперь легко заметить, что все пути из А в С проходят через 2 вершины: Е и В • • • Вся задача разбилась на 3 последовательные и независимые части: Путь от А до Е Путь от Е до В Путь от В до С На каждом участке найдём кратчайший путь: АЕ = min (5, 3+3) = 5 ЕВ = min (4, 1+1) = 2 ВС = 1 и получим ответ: 5 + 2 + 1 = 8

Замечания • В большинстве тренировочных задач требуется найти путь от начального пункта до конечного. Замечания • В большинстве тренировочных задач требуется найти путь от начального пункта до конечного. Рассмотренный пример показывает, что это не всегда так!

Задача 2. Грунтовая дорога проходит последовательно через населённые пункты A, B, C, D. При Задача 2. Грунтовая дорога проходит последовательно через населённые пункты A, B, C, D. При этом длина дороги между А и В равна 15 км, между В и С – 45 км, между С и D – 20 км. Расстояние по воде между А и D равно 60 км, и работает паромное сообщение. Чему равно минимальное время движения велосипедиста из пункта А в пункт С, если его скорость по грунтовке равна 20 км/час, а паром движется со скорость 40 км/час?

Решение • Нарисуем граф, соответствующий плану дорог между пунктами • На этом графе путь Решение • Нарисуем граф, соответствующий плану дорог между пунктами • На этом графе путь от А до D – по воде, путь А – В – С – D по грунтовке. • У нас есть два варианта пути от А до С: • 1. По грунтовке от А до В и от В до С • 2. На пароме от А до D и по грунтовке от D до С в обратную сторону

 • Для наглядности каждой дороге (ребру графа) припишем числа. • Но вместо расстояний • Для наглядности каждой дороге (ребру графа) припишем числа. • Но вместо расстояний дорогам припишем время, затрачиваемое велосипедистом на их преодоление. • • • Здесь все времена записаны как дроби (путь/скорость) Вычислим время для каждого варианта пути и найдём минимальное: А-В-С время = (15 + 45) / 20 = 3 часа A-D-C время = 60/40 + 20/20 = 2. 5 часа Ответ: 2. 5 часа

Итоги раздела • Рисование картинок или схем (графа) может помочь при решении некоторых задач, Итоги раздела • Рисование картинок или схем (графа) может помочь при решении некоторых задач, т. к. в них условия видны более наглядно!

Раздел 2. Динамика • Более точное название темы динамическое программирование. • Суть метода состоит Раздел 2. Динамика • Более точное название темы динамическое программирование. • Суть метода состоит в том, что при решении некоторой задачи мы не знаем точного пути, по которому нужно идти к правильному ответу. Таких путей может быть несколько, поэтому мы параллельно помним о нескольких вариантах путей решения задачи. • Альтернативой этому методу являются «жадные» алгоритмы, когда на каждом шаге решения у нас есть один точный путь и мы идём к ответу по нему, выбирая на каждом этапе из нескольких один – самый лучший.

Задача 3. На рисунке приведена схема дорог, связывающих города А, Б, В, Г, Д, Задача 3. На рисунке приведена схема дорог, связывающих города А, Б, В, Г, Д, Е, Ж, И, К, Л. По каждой дороге можно двигаться только в одном направлении, указанном стрелкой. Сколько существует различных путей из города А в город Л?

Первая попытка решения • Давайте попробуем решить эту задачу «в лоб» – выпишем все Первая попытка решения • Давайте попробуем решить эту задачу «в лоб» – выпишем все варианты путей от А до Л. • Приведу несколько примеров таких путей в виде последовательности букв: • А-Б-Д-И-Л по самому верху схемы • А-В-Б-Д-И-Л • А-В-Д-И-Л • … • А-Г-Ж-К-Л по самому низу • ВЫВОД: • Легко ошибиться и пропустить какой-то путь или наоборот, записать и учесть один путь дважды!

Решение методом динамического программирования • ИДЕЯ: • Последовательно каждому городу будем приписывать натуральное число Решение методом динамического программирования • ИДЕЯ: • Последовательно каждому городу будем приписывать натуральное число – сколько путей ведут в данный город из города А. • На каждом шаге число будет приписываться только одному выбранному городу. • Это число будет приписываться один раз и в дальнейшем меняться не будет! • Первый город в любом пути – это город А. • Сколько путей ведут в него из него же самого? • Т. е. сколько есть путей из А в А?

Существует 1 путь из А в А!!! Этот путь состоит в том, что никуда Существует 1 путь из А в А!!! Этот путь состоит в том, что никуда двигаться не надо, т. е. путь длины 0! Мы ведь и так уже в городе А. • Как выбрать очередной город? • На очередном шаге мы должны найти такой город, куда ведут стрелки только из городов с числами! • Если таких городов несколько, то выбираем любой из них. • На 2 -м шаге выбираем город, куда ведут стрелки только из города А (только у него есть приписанное число): • Такой город только один – В • Города Б и Г не подходят, потому что в них стрелки ведут не только из А, но и из В! • Таким образом городу В приписываем число 1.

Какое число приписывать очередному городу? • Суммируем все числа, которые уже приписаны городам, откуда Какое число приписывать очередному городу? • Суммируем все числа, которые уже приписаны городам, откуда ведут стрелки в выбранный очередной город – полученную сумму припишем этому городу. • Приведём города и приписанные числа в порядке их заполнения, а не по алфавиту: • А – 1 • В – 1 • Б – 2 (1 + 1) • Г – 2 (1 + 1) • Д – 3 (1 + 2) • Ж – 3 (1 + 2) • Е – 4 (1 + 3) • К – 3 (3) • И – 7 (3 + 4) • Л – 17 (7 + 4 + 3)

 • Пояснения: • Я все числа выписал в отдельной таблице, а вам будет • Пояснения: • Я все числа выписал в отдельной таблице, а вам будет удобнее их рисовать прямо на самом графе. • Городам Б и Г можно в любом порядке приписать число, а также парам городов Д и Ж, Е и К. • Для города И суммируются два числа, соответствующие городам Д (3) и Е (4). • Ответ: 17 различных путей ведут из А в Л

Почему в этой задаче метод ДП даёт правильный результат, в чём его «оправдание» ? Почему в этой задаче метод ДП даёт правильный результат, в чём его «оправдание» ? • Если для некоторого города мы правильно вычислили количество путей, ведущих в него из города А, то для следующего города мы удлиняем все эти пути (точнее каждый из путей) еще на одну стрелку (дорогу). • Таким образом, для нового города мы суммируем все пути, ведущие из предыдущих для него города.

Задача 4. У исполнителя «Утроитель» есть две команды, которым присвоены номера: 1. прибавь 1, Задача 4. У исполнителя «Утроитель» есть две команды, которым присвоены номера: 1. прибавь 1, 2. умножь на 3. Первая из них увеличивает число на экране на 1, вторая – утраивает его. Программа для «Утроителя» – это последовательность команд. Сколько есть программ, которые число 1 преобразуют в число 29?

Решение • Замечания. • 1. В этой задаче, как и в предыдущей, не требуется Решение • Замечания. • 1. В этой задаче, как и в предыдущей, не требуется перечислить все такие программы. Нужно только посчитать их количество. • 2. Внешне эта задача сильно отличается от предыдущей, но мы применим к ней тот же самый метод.

Метод решения этой задачи с помощью дерева • Будем рисовать дерево и в узлах Метод решения этой задачи с помощью дерева • Будем рисовать дерево и в узлах (вершинах) его будем записывать полученные числа. • Для удобства рисования дерево будем строить корнем сверху и ветки будут направлены вниз. В корневом узле будет стоять начальное число 1. • На ветках будем рисовать формулу для получения нового числа: • +1 – прибавить 1 • *3 – умножить на 3 • Таким образом, ход решения задачи будем изображать в виде графа.

 • На этом рисунке приведено только начало этого дерева, но уже по нему • На этом рисунке приведено только начало этого дерева, но уже по нему можно заметить некоторые особенности: • Если нужно получить большое число, то размер дерева может быть достаточно большим – и оно растёт вглубь и вширь! • Там, где будут получаться числа, больше искомого, дерево строить не будем. • В конце надо будет посчитать количество узлов, в которых появилось наше искомое число.

Решение методом ДП • Обозначим через Rn количество программ для преобразования числа 1 в Решение методом ДП • Обозначим через Rn количество программ для преобразования числа 1 в число n. Тогда можно вывести простые формулы для вычисления: • Rn = Rn-1 , если число n не делится на 3 • Rn = Rn-1 + Rn/3 , если число n делится на 3 • Первая формула означает, что число n можно получить из числа n-1, удлинив на 1 команду (+1) каждую программу для получения числа n 1. • Вторая формула означает, что мы можем использовать все программы для получения числа n-1, удлиняя их на 1 команду, но также можем получить число n из числа n/3, удлиняя каждую программу на команду (*3). • Теперь последовательно выпишем все числа Rn для n=1, 2, 3… 29.

Результаты вычислений: • • • • R 1 = 1 ? ? ? R Результаты вычислений: • • • • R 1 = 1 ? ? ? R 18 = 12 R 2 = 1 = R 1 R 19 = R 20 = 12 R 3 = 2 = R 2 + R 1 R 21 = 15 R 4 = 2 = R 3 R 22 = R 23 = 15 R 5 = 2 = R 4 R 24 = 18 R 6 = 3 = R 5 + R 2 R 25 = R 26 = 18 R 7 = 3 = R 6 R 27 = 23 R 8 = 3 = R 7 R 28 = R 29 = 23 R 9 = 5 = R 8 + R 3 R 10 = R 11 = 5 R 12 = 7 R 13 = R 14 = 7 R 15 = 9 R 16 = R 17 = 9

Программа для проверки результатов вычислений: • • • • # include <iostream> using namespace Программа для проверки результатов вычислений: • • • • # include using namespace std; int main () { const int N=10000; int R [N], n; // заведём большой массив, но использовать будем только его часть cin >> n; R [1] = 1; for ( int i=2; i <= n; i++ ) // в цикле вычисляем элементы массива по выведенным формулам if ( i%3 ) R [i] = R [i-1]; // формула для номеров, не делящихся на 3 else R [i] = R [i-1] + R [i/3]; cout << R [n]; return 0; }

Возможные варианты этой задачи • Разные правила получения новых чисел • Начальное число не Возможные варианты этой задачи • Разные правила получения новых чисел • Начальное число не 1, а какое-то другое • Если изменились команды нашего «Утроителя» , то надо внести изменения в проверяющую программку

Раздел 3. Рекурсия • Последовательность чисел задаётся рекуррентной формулой, если в формулу для общего Раздел 3. Рекурсия • Последовательность чисел задаётся рекуррентной формулой, если в формулу для общего члена входят другие члены этой последовательности. • Самый простой пример – это факториалы натуральных чисел. Считается, что факториал 0 равен 1( 0! = 1 ), а последующие факториалы вычисляются через предыдущие: n! = (n-1)!*n. • Таким образом легко вычислить последовательно факториалы натуральных чисел: • 1! = 1, 2! = 2, 3! = 6, 4! = 24, 5! = 120, 6! = 720 и т. д.

 • Другой пример немного сложнее – последовательность чисел Фибоначчи в классическом виде. Здесь • Другой пример немного сложнее – последовательность чисел Фибоначчи в классическом виде. Здесь каждый элемент последовательности вычисляется как сумма двух предыдущих, а первые два члена задаются: • F(1) = 1, F(1) = 1 • F(n) = F(n-1) + F(n-2) • Задача состоит в том, что надо вычислить число Фибоначчи с заданным номером K. • Для решения этой задачи мы будем последовательно вычислять эти числа: • F (3) = 2 • F (4) = 3 • F (5) = 5 • F (6) = 8 • и т. д. до нужного номера. • Например, F (11) = 89 По другому варианту записи F 11 = 89

Задача 5. Алгоритм вычисления функции f (n), где n – натуральное число задан следующими Задача 5. Алгоритм вычисления функции f (n), где n – натуральное число задан следующими соотношениями: F (n) = 2 при n <= 2, F (n) = F (n-1) + 2*F (n-2) при n > 2. Чему равно значение F (7)?

Решение. • Для решения этой задачи будем последовательно вычислять значения функции по заданным формулам: Решение. • Для решения этой задачи будем последовательно вычислять значения функции по заданным формулам: • F (1) = 2 • F (2) = 2 • F (3) = 6 = 2 + 2*2 • F (4) = 10 = 6 + 2*2 • F (5) = 22 = 10 + 2*6 • F (6) = 42 = 22 + 2*10 • F (7) = 86 = 42 + 2*22 • Ответ: 86

Задача 6. Максимальное число L(n) областей, на которые плоскость делится n прямыми, можно вычислить Задача 6. Максимальное число L(n) областей, на которые плоскость делится n прямыми, можно вычислить с помощью рекуррентного соотношения: L(n)=L(n− 1)+n при натуральных n≥ 1 L(0)=1 Каково максимальное число областей, на которые плоскость делится десятью прямыми?

Решение • Как и в предыдущей задаче последовательно будем вычислять значения функции L: • Решение • Как и в предыдущей задаче последовательно будем вычислять значения функции L: • L (0) = 1 • L (1) = 2 = 1+1 • L (2) = 4 = 2+2 • L (3) = 7 = 4+3 • L (4) = 11 = 7+4 • L (5) = 16 = 11+5 • L (6) = 22 = 16+6 • L (7) = 29 = 22+7 • L (8) = 37 = 29+8 • L (9) = 46 = 37+9 • L (10) = 56 = 46+10 • Ответ: 56

Выводы • Решения задач легко находятся аккуратными последовательными вычислениями по заданным формулам (соотношениям) • Выводы • Решения задач легко находятся аккуратными последовательными вычислениями по заданным формулам (соотношениям) • Задачу 4 из предыдущего раздела можно отнести и к данному разделу. • Совет. Для отладки задач подобного рода можно написать простую программу для проверки ответов. Например, для задачи-6: • • • VAR L : array [0. . 20] of integer; i : integer; BEGIN L [0] : = 1; FOR i: =1 TO 10 DO L [i] : = L [i-1] + I; WRITELN (L [10]) END. • Эту программу легко переделать для других аналогичных задач.

 • Задача 7. Строки (цепочки символов латинских букв) создаются по следующему правилу. Первая • Задача 7. Строки (цепочки символов латинских букв) создаются по следующему правилу. Первая строка состоит из одного символа – латинской буквы «А» . Каждая из последующих цепочек создается такими действиями: в очередную строку сначала записывается буква, чей порядковый номер в алфавите соответствует номеру строки (на i-м шаге пишется i-я буква алфавита), к ней слева дважды подряд приписывается предыдущая строка. Вот первые 4 строки, созданные по этому правилу: • (1) A • (2) AAB • (3) AABAABC • (4) AABAABCD • Латинский алфавит (для справки): ABCDEFGHIJKLMNOPQRSTUVWXYZ • Запишите шесть символов подряд, стоящие в седьмой строке со 117 -го по 122 -е место (считая слева направо)

Попытка решить задачу «в лоб» • Будем последовательно выписывать строки, полученные по заданному правилу Попытка решить задачу «в лоб» • Будем последовательно выписывать строки, полученные по заданному правилу • (1) A • (2) AAB • (3) AABAABC • (4) AABAABCD • (5) AABAABCAABAABCDE • (6) • AABAABCAABAABCDEAABAABCAABAAB CDAABAABCDEF • (7) AABAABCAABAABCDEAABAABCAABAAB CDAABAABCDEFAABAABCDAABAABCAAB AABCDEAABAABCAABAABCDEFG • Занятие достаточно утомительное, если нет под рукой текстового редактора, в котором можно копировать одинаковые куски

 • Если нигде не ошиблись, то легко найти нужный ответ. • Давайте этот • Если нигде не ошиблись, то легко найти нужный ответ. • Давайте этот вариант оставим как запасной на случай, если не придумаем другой, более простой способ

Рекурсивное решение с конца • • • 1. Для начала вычислим длину каждой строки, Рекурсивное решение с конца • • • 1. Для начала вычислим длину каждой строки, начиная со 2 -й и до 7 -й: Длина 1 -й строки равна 1 (21) Длина 2 -й строки равна 3 (22) Длина 3 -й строки равна 7 (23) И т. д. длина каждой строки равна очередной степени двойки без 1 • Длина 7 -й строки равна 127 (27) • 2. Седьмая строка состоит из двух шестых (по 63 символа каждая) и очередной буквы алфавита в конце (F). Позиции со 117 -й по 122 -ю находятся во втором экземпляре шестой строки, входящей в седьмую. • Если откинуть первый экземпляр шестой строки, то искомые позиции находятся внутри второй шестой строки на местах с 54 -го (117 -63) по 59 -е (122 -63).

 • Таким образом мы свели задачу к поиску букв в шестой строке на • Таким образом мы свели задачу к поиску букв в шестой строке на местах с 54 -го по 59 -е! • 3. Аналогично, эту задачу можно свести к пятой строке, т. к. шестая строка (длиной 63 символа) состоит из 2 -х экземпляров пятой (по 31 символу каждая) и буквы в конце Е. • Позиции 54 -59 опять находятся после середины, значит во втором экземпляре пятой строки внутри шестой на местах с 23 -го по 28 -е. • 4. Продолжим аналогии: • Нужные позиции находятся на местах с 8 -го по 13 -е в четвёртой строке. • Четвёртая строка нам дана в условии и легко найти в ней нужные позиции и получить ответ. • Ответ: ААВААВ

Дополнительные замечания • • • • • Ниже приведён пример простой программы на языке Дополнительные замечания • • • • • Ниже приведён пример простой программы на языке Си++ для задачки с символьными строками # include # include using namespace std; int main () { string s = "A", t = "A"; cout << "1 " << s << " " << s. length () << endl; for ( int k=2; k <= 7; k++ ) { t [0]++; s = s + t; cout << k << " " << s. length () << endl; } for ( int k=116; k < 122; k++ ) cout << s [k]; return 0; }

Вывод этой программы будет таким: печатается номер строки, сама строка и её длина. После Вывод этой программы будет таким: печатается номер строки, сама строка и её длина. После последней строки печатается ответ к этой задаче: ААВААВ 1 A 1 2 AAB 3 3 AABAABC 7 4 AABAABCD 15 5 AABAABCAABAABCDE 31 6 AABAABCAABAABCDEAABAABCDAABAABCDEF 63 • 7 AABAABCAABAABCDEAABAABCDAABAABCDEFAABAABCAABAABCDEAABAABCAABAAB CDAABAABCDEFG 127 • • AABAAB

Замечание к дополнительному замечанию • Конечно, на экзамене не удастся с помощью такой программы Замечание к дополнительному замечанию • Конечно, на экзамене не удастся с помощью такой программы проверить правильность ответа, но при подготовке это может помочь.

Задача 8. У исполнителя КУЗНЕЧИК две команды: 1) прибавь 7 2) вычти 3 Первая Задача 8. У исполнителя КУЗНЕЧИК две команды: 1) прибавь 7 2) вычти 3 Первая из них увеличивает число на экране на 7, вторая – уменьшает на 3 (отрицательные числа не допускаются). Программа для КУЗНЕЧИКА – это последовательность команд. Сколько различных чисел можно получить из числа 0 с помощью программы, которая содержит ровно 10 команд?

Решение • Если в программе 10 команд и каждая из них может быть одного Решение • Если в программе 10 команд и каждая из них может быть одного из двух видов, то всего существует 210 (1024) различных программ. • Можно заметить, что обе команды противоположные другу, одна увеличивает число, другая уменьшает. Поэтому, если поменять местами две разные команды местами, то результат будет одинаковым. Значит многие программы, которые отличаются друг от друга только порядком команд, дают одинаковые числа в результате. • Например, программы из 3 -х команд 112, 121, 211 дают в результате одно и тоже число – на 11 больше исходного (+14 -3). • Таким образом, принципиально разными с точки зрения результата являются такие программы, которые отличаются количеством команд первого и второго типа, а не взаимным расположением.

 • • • Перечислим все такие разные программы длины 10: 1) 11111 2) • • • Перечислим все такие разные программы длины 10: 1) 11111 2) 111112 3) 111122 4) 1111111222 5) 1111112222 6) 1111122222 7) 1111222222 8) 1112222222 9) 112222 10) 122222 11) 22222

 • По условию нам подходят не все программы, а только те, которые не • По условию нам подходят не все программы, а только те, которые не дают отрицательных чисел. • Очевидно нам не подходит последняя программа, которая содержит только команды вычитания – она даёт число -30. • Ответ на эту задачу можно получить математически, если составить и решить систему. • Пусть А – число команд типа 1, В – число команд типа 2. • Тогда А + В = 10 • И 7*А – 3*В >= 0 • Решив систему, мы найдём, что А >= 3, т. е. из списка перечисленных программ нам подойдут первые 8, в которых команд 1 -го типа не меньше 3 -х. • Ответ: 8

Тагиров Равиль Рафгатович • • Ravil. Tagirov@kpfu. ru jamalir@yandex. ru jamalir@mail. ru Rawil. Tagirov@gmail. Тагиров Равиль Рафгатович • • Ravil. Tagirov@kpfu. ru jamalir@yandex. ru jamalir@mail. ru Rawil. Tagirov@gmail. com