Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Magistr.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
1.85 Mб
Скачать
  1. Нахождение минимальных, максимальных элементов массива.

1

2

3

4

5

6

7

max = mass[0];//Помещаем значения 1-го элемента

min = mass[0];//массива в переменные

for(int r = 1; r<N; r++)

{

if(max < mass[r]) max = mass[r]; //если значение элемента больше значения переменной max, то записываем это значение в переменную

if(min > mass[r]) min = mass[r]; //аналогично и для min

}

  1. Задачи динамического программирование. Построение рекуррентных соотношений.

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

  • Зависимость элементов динамики друг от друга. Такая зависимость может быть прямо дана в условии (так часто бывает, если это задача на числовые последовательности). В противном случае вы можете попытаться узнать какой-то известный числовой ряд (вроде тех же чисел Фибоначчи), вычислив первые несколько значений вручную. Если вам совсем не повезло – придётся думать 

  • Значение начальных состояний. В результате долгого разбиения на подзадачи вам необходимо свести функцию либо к уже известным значениям (как в случае с Фибоначчи — заранее определены первые два члена), либо к задаче, решаемой элементарно.

  1. Алгоритмы нахождения палиндрома в строке.

Палиндро́м — число (например, 404), буквосочетание, слово или текст, одинаково читающееся в обоих направлениях. Иногда палиндромом называют любой симметричный относительно своей середины набор символов.(выдержка из Википедии)

Алгоритм Манакера

[править]Идея

Алгоритм, который будет описан далее, отличается от наивного тем, что использует значения, посчитанные ранее. Будем поддерживать границы самого правого из найденных палиндромов —  . Итак, пусть мы хотим вычислить   — т.е. длину наибольшего палиндрома с центром в позиции  . При этом все предыдущие значения в массиве   уже посчитаны. Возможны два случая:

  1. , т.е. текущая позиция не попадает в границы самого правого из найденных палиндромов. Тогда просто запустим наивный алгоритм для позиции  .

  2. . Тогда попробуем воспользоваться значениями, посчитанным ранее. Отразим нашу текущую позицию внутри палиндрома  . Поскольку   и   — симметричные позиции, то если  , мы можем утверждать, что и  . Это объясняется тем, что палиндром симметричен относительно своей центральной позиции. Т.е. если имеем некоторый палиндром длины   с центром в позиции  , то в позиции  , симметричной   относительно отрезка   тоже может находиться палиндром длины  . Это можно лучше понять, посмотрев на рисунок. Снизу фигурными скобками обозначены равные подстроки. Однако стоит не забыть про один граничный случай: что если   выходит за границы самого правого палиндрома? Так как информации о том, что происходит за границами это палинлрома у нас нет (а значит мы не можем утверждать, что симметрия сохраняется), то необходимо ограничить значение   следующим образом:  . После этого запустим наивный алгоритм, который будет увеличивать значение  , пока это возможно.

После каждого шага важно не забывать обновлять значения  .

Заметим, что массив   считается аналогичным образом, нужно лишь немного изменить индексы.

[править]Псевдокод

Приведем код, который вычисляет значения массива  :

// — исходная строка

int[] calculate1(string s):

int l = 0

int r = -1

for i = 1 to n

int k = 0

if i <= r

k = min(r - i, d[r - i + l])

while i + k + 1 <= n and i - k - 1 > 0 and s[i + k + 1] == s[i - k - 1]

k++

[i] = k

if i + k > r

l = i - k

r = i + k

return

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]