
- •Глава 2. Перебор и методы его сокращения
- •2.1. Перебор с возвратом
- •2.1.1. Общая схема
- •2.1.2. Задача о расстановке ферзей
- •2.1.3. Задача о шахматном коне
- •2.1.4. Задача о лабиринте
- •2.1.5. Задача о парламенте
- •2.1.6. Задача о рюкзаке (перебор вариантов)
- •2.1.7. Задача о коммивояжере (перебор вариантов)
- •2.1.8. Задача о секторах
- •Входные и выходные данные
- •2.2. Динамическое программирование
- •2.2.1. Задача о Черепашке
- •2.2.2. Треугольник
- •2.2.3 Степень числа
- •2.2.4. Автозаправка
- •2.2.5. Алгоритм Нудельмана-Вунша
- •2.2.6. Разбиение выпуклого n-угольника
- •2.2.7. Задача о рюкзаке (динамическая схема)
- •2.2.8. Задача о паркете
- •2.2.9. «Канадские авиалинии»
- •2.3. Метод «решета»
- •2.3.1. Решето Эратосфена
- •2.3.2. Быки и коровы
- •2.4. Задачи
2.2.2. Треугольник
На рисунке изображен треугольник из чисел. Напишите программу, которая вычисляет наибольшую сумму чисел, расположенных на пути, начинающемся в верхней точке треугольника и заканчивающемся на основании треугольника.
|
|
|
|
7 |
|
|
|
|
|
|
|
3 |
|
8 |
|
|
|
|
|
8 |
|
1 |
|
0 |
|
|
|
2 |
|
7 |
|
4 |
|
4 |
|
4 |
|
5 |
|
2 |
|
6 |
|
5 |
-
Каждый шаг на пути может осуществляться вниз по диагонали влево или вниз по диагонали вправо.
-
Число строк в треугольнике > 1 и <100.
-
Треугольник составлен из целых чисел от 0 до 99.
Рассмотрим идею решения на примере, приведенном в тексте задачи. Входные данные запишем в матрицу D. Она, для примера, имеет вид:
7 0 0 0 0
3 8 0 0 0
8 1 0 0 0
2 7 4 4 0
4 5 2 6 5
R[1,1]=D[1,1]
R[i,j]=max(D[i,j]+R[i-1,j],D[i,j]+R[i-1,j-1])
для i=2..N; j=1..i.
Ее вид:
0 7
0 10 15
0 18 16 15
0 20 25 20 19
0 24 30 27 26 24
2.2.3 Степень числа
Даны два натуральных числа n и k. Требуется определить выражение, которое вычисляет kn . Разрешается использовать операции умножения и возведения в степень, круглыми скобками и переменной с именем k.Умножение считается одной операцией, возведению в степень q соответствует q-1 операция. Найти минимальное количество операций, необходимое для возведения в степень n. Желательно сделать это для как можно больших значений n.
Пример. При n=5 необходимо три операции - (k*k)2*k.
Определим массив Op, его элемент Op[i] предназначен для хранения минимального количества операции при возведении в степень i (Op[1]=0). Для вычисления выражения, дающего n-ю степень числа k, арифметические операции применяют в некоторой последовательности, согласно приоритетам и расставленным скобкам. Рассмотрим последнюю примененную операцию.
Если это было умножение, тогда сомножителями являются натуральные степени числа k, которые в сумме дают n. Степень каждого из сомножителей меньше n, и ранее вычислено, за какое минимальное число операций ее можно получить. Итак:
opn1:=min{по всем p:1£p<n, Op[p]+Op[n-p]+1}.
Если это возведение в степень:
opn2:=min{ для всех p (¹1) - делителей n, Op[n div p]+p-1}.
Результат - Op[n]=min(opn1,opn2). Фрагмент реализации:
......
Op[1]:=0;
for n:=2 to ???? do begin
opn:=n;{opn - рабочая переменная}
for p:=1 to n-1 do begin
opn:=Min(opn,Op[p]+Op[n-p]+1);{Min - функция поиска минимума двух чисел}
if (n mod p=0) and (p<>1) then opn:=Min(opn,Op[n div p]+p-1);
end;
Op[n]:=opn;
end;
....