Задача о расстановке знаков в выражении
Задача о расстановке знаков в выражении — задача о нахождении максимального значения выражения, полученного расстановкой знаков
и скобок в последовательности .Содержание
Решение
Данная задача решается с использованием принципа оптимальности на подотрезке[1]. Введём матрицу размером , где будет равен максимальному значению, достигаемому на подотрезке .
Получаем следующие соотношения:
Вычислим элементы таблицы
, тогда ответом на задачу будет значение .Доказательство
Рассмотрим ее, например, в такой формулировке. В арифметическом выражении, операндами которого являются целые числа, а операциями — бинарные арифметические операции “+” и “*”, расставить скобки так, чтобы результат оказался максимальным Подзадачами, через которые мы будем выражать оптимальное решение, будут задачи об оптимальной расстановке скобок в произведениях наших операндов, начиная с i-го и заканчивая j-м. Запоминать результат оптимального решения соответствующей подзадачи мы будем в элементе a[i, j] матрицы, размером n´n, диагональные элементы которой (a[i, i]) равны операндам, а для i > j все элементы равны 0. Пусть мы хотим подсчитать значение арифметического выражения для операндов, начиная с i-го и заканчивая j-м для i < j. Если мы предположим, что последней будет выполняться арифметическая операция, расположенная после операнда с номером k (i £ k < j) и эта операция — сложение, то результат подсчета будет равен сумме элементов a[i, k] и a[k+1, j] нашей матрицы. С умножением ситуация несколько более сложная. Так как операндами могут быть и отрицательные числа, то для нахождения максимума из произведений нужно знать не только максимальные, но и минимальные значения для арифметических операций над операндами с i-го по k-й и с k+1-го по j-й соответственно. Значит для любой последовательности операндов нужно хранить значение как максимально, так и минимально возможного результата выполнения арифметических операций над ними. Однако, дополнительная матрица для хранения минимальных значений не нужна. Так как для i > j матрица a не заполнена, мы можем отвести эти элементы для хранения минимумов, только запоминать результат решения этой подзадачи для операндов, начиная с i-го и заканчивая j-м, мы будем в элементе a[j, i]. Тогда в общем случае, если после k-го операнда стоит операция умножения (i £ k < j), то максимальный результат будет равен max(a[i, k]´ a[k+1, j], a[k, i]´ a[j, k+1], a[i, k]´ a[j, k+1], a[k, i]´ a[k+1, j]).
Реализация
// d - матрица как в описании; a - последовательность из n элементов; i, j, k - счётчики for i := 1 to n do d[i][i] := a[i]; for i := n - 1 downto 1 do for j := i + 1 to n do for k := i to j - 1 do d[i][j] := max(d[i][j], max(d[i][k] + d[k+1][j], d[i][k] * d[k+1][j])); write(d[1][n]); // вывод ответа
Пример
Пусть дана последовательность 2, 1, 1, 2. Таблица
для неё будет выглядеть так:j = 1 | j = 2 | j = 3 | j = 4 | |
i = 1 | 2 | 3 | 4 | 9 |
i = 2 | 0 | 1 | 2 | 4 |
i = 3 | 0 | 0 | 1 | 3 |
i = 4 | 0 | 0 | 0 | 2 |
Источники
- Кормен, Т., Лейзерсон, Ч., Ривест, Р., Штайн, К. Глава 15. Динамическое программирование // Алгоритмы: построение и анализ = Introduction to Algorithms / Под ред. И. В. Красикова. — 2-е изд. - 300стр. — М.: Вильямс, 2005. — 1296 с. — ISBN 5-8459-0857-4